1.前篇
在讨论访问控制权限之前,有必要了解类库的概念,因为使用访问控制权限是为了提供有限的字段或方法给客户端开发人员
(public标志)
,而提供给客户端开发人员,则需要牵涉到将自己构件的类库进行打包,这就引入了类库的概念。(可直接跳过这一节)
1.1类库的概念
类库是将各构件捆绑到一个内聚的类库单元中,使用
package
关键字(包),例如package com.zxr.xxx``,其中
com.zxr.xxx```也代表了代码目录。
1.2包:库单元
包中含有一组类,他们在单一的名字空间被组织在一起。
例如,我们要实例化一个ArrayList对象,可以像下面这样做
java.util.ArrayList lists = new ArrayList<>();
但是显然这样让代码变得很冗余,于是我们使用import
关键字,代码如下:
import java.util.ArrayList;
ArrayList lists = new ArrayList<>();
我们之所以要导入,就是提供了一个管理名字空间的机制。所有类成员的名称都是彼此分离的。这样A类种有个f()
方法和B类种相同的方法不会彼此冲突。
但是如果类的名字冲突了该怎么办?,这个时候就要用到package
将不同类分隔开。
1.3创建一个自己的类库
package
放置于除代码的第一行之中,声明该类是属于哪个包之下;
额外说明:我们在平时编写代码的时候大多时候并没有进行package声明,是因为在构建项目的时候,存在一个default包,如果使用ecplise的话在创建java项目时,会提示你输入包名,不输入时默认为default。
下面是一个简单构建代码
package com.zxr.learn;
/**
* Print类
*/
public class Print {
public static void print(Object str){
System.out.print(str);
}
}
我们在来看一下前文中提到的代码目录:
image.png如果要在外部进行引用时,使用import
关键字:
import com.zxr.learn.Print;
public class Chapter6 {
public static void main(String args[]){
Print print = new Print();
}
}
在这里额外说明一下,有一种静态导入方式(这是我之前初学java没有用过的方法),举个栗子,我对System.out.println()
已经算是深恶痛绝了,明明在c/python等其他语言一个print()
就搞定的事,却搞得这么复杂。以前我为了偷懒,使用了一个基类进行常用方法的封装,其他类在继承就行了,就像下面这样:
public class Base {
protected static void println(Object str){
System.out.println(str);
}
protected static void print(Object str){
System.out.print(str);
}
}
public class Chapter6 extends Base{
public static void main(String args[]){
print("xxxxx");
}
}
偶然间在<<Thinking in Java>>中看到import static
方式也不错,如下:
import static com.zxr.learn.Print.print;
public class Chapter6{
public static void main(String args[]){
print("fff");
}
}
嘛,算是一种用法。
好了,啰嗦多了,下面进入主题。
2.Java访问权限修饰词
java给了三个关键词用于访问权限控制,分别是
public,protected,private
,但是java访问权限机制其实是有四种方式的,还有一种默认方式,也就是说你对域或方法直接定义而不加关键词时,采用default方式。所以不论你如何对其进行定义,所有事物都具有某种形式的访问控制权限。
下面给出4种访问权限的区别与用法,权限范围由大到小:
2.1 public:接口访问权限
具有最大的访问权限,可以访问任何一个在classpath下的类、接口、异常等。它往往用于对外的情况,也就是对象或类对外的一种接口的形式。
2.2 protected:继承访问权限
主要的作用就是用来保护子类的。它的含义在于子类可以使用它修饰的成员,其他的不可以,它相当于传递给子类的一种继承的东西。
2.3 default:包访问权限
有时候也称为friendly,它是针对本包访问而设计的,任何处于本包下的类、接口、异常等,都可以相互访问,即使是父类没有用protected修饰的成员也可以。
2.4 private:无法访问权限!
访问权限仅限于类的内部,是一种封装的体现,例如,大多数成员变量都是修饰符为private的,它们不希望被其他任何外部的类访问。
最后给出一张表:
类内部 | 子类 | 本包 | 外部包 | |
---|---|---|---|---|
public | Y | Y | Y | Y |
protected | Y | Y | Y | N |
default | Y | N | Y | N |
private | Y | N | N | N |
访问权限从大到小
3.类的访问权限
3.1关于类的一些说明
- 每个编译单元(文件)只能有一个
public
类 -
public
类的名称必须完全与含有该编译单元的文件名相同 - 虽然不常用,但是编译单元内完全不带
public
也是可以的,但是请不要这样使用。
3.2类的访问权限
对于类的访问权限,仅有两个选择,包访问权限或
public
,如果不希望其他任何人对该类拥有访问权限,可以把所有的构造器都指定为private,从而阻止任何人创建给类对象。但是又一个例外,就是在该类的static
成员内部可以创建。
下面举个例子:
class Test {
private Test() {
}
}
public static void main(String args[]) {
Test myTest = new Test();//这样调用编译器会报错
}
image.png
现在我们可以对Test进行加工:
class Test {
private static Test test;
private Test() {
}
public static Test getInstance(){
return new Test();
}
}
public class Chapter6 extends Base {
public static void main(String args[]) {
// Test myTest = new Test();
Test myTest = Test.getInstance();
}
}
如果你想在返回Test对象引用前做一些额外工作,或者记录到底产生了多少个Test对象,这样做是大有裨益的。
或者:
class Test {
private static Test test = new Test();
private Test() {
}
public static Test getInstance(){
return test;
}
}
public class Chapter6 extends Base {
public static void main(String args[]) {
// Test myTest = new Test();
Test myTest = Test.getInstance();
}
}
singleton单例模式的用法。
大概就这么多吧。
网友评论