2. 访问控制修饰符
-
public : 对所有类可见
使用对象:类、接口、变量、方法
-
protected : 对同一包内的类和所有子类可见
使用对象:变量、方法。 注意:不能修饰类(外部类)
-
default (即缺省,什么也不写): 在同一包内可见,不使用任何修饰符
使用对象:类、接口、变量、方法。
-
private : 在本类中可见
使用对象:变量、方法。 注意:不能修饰类(外部类)
private和protected修饰符不能用以修饰类/接口
2.1 公有访问修饰符-public
被声明为 public 的类、方法、构造方法和接口能够被任何其他类访问。
如果几个相互访问的 public 类分布在不同的包中,则需要导入相应 public 类所在的包。
由于类的继承性,类所有的公有方法和变量都能被其子类继承。
2.2 受保护的访问修饰符-protected
protected 又称继承访问权限
protected 需要从以下两个点来分析:
-
子类与基类在同一包中:被声明为 protected 的变量、方法和构造器能被同一个包中的任何其他类访问;
-
子类与基类不在同一包中:在子类中,子类实例可以访问其从基类继承而来的 protected 方法,而不能访问基类实例的protected方法
子类能访问 protected 修饰符声明的方法和变量,这样就能避免不相关的类使用这些方法和变量。
在碰到涉及protected成员的调用时,首先要确定出该protected成员来自何方,其可见性范围是什么,然后就可以判断出当前用法是否可行了
package p2;
class MyObject2 {
protected Object clone() throws CloneNotSupportedException{
return super.clone();
}
}
package p22;
public class Test2 extends MyObject2 {
public static void main(String args[]) {
MyObject2 obj = new MyObject2();
obj.clone(); // Compile Error ----(1)
Test2 tobj = new Test2();
tobj.clone(); // Complie OK ----(2)
}
}
对于(1)而言,clone()方法来自于类MyObject2本身,因此其可见性为包p2及MyObject2的子类,虽然Test2是MyObject2的子类,但在Test2中不能访问基类MyObject2的protected方法clone(),因此编译不通过;
对于(2)而言,由于在Test2中访问的是其本身实例的从基类MyObject2继承来的的clone(),因此编译通过。
2.3 默认访问修饰符-不使用任何关键字
使用默认访问修饰符声明的变量和方法,对同一个包内的类是可见的。
接口里的变量都隐式声明为 public static final,而接口里的方法默认情况下访问权限为 public。
2.4 私有访问修饰符-private
被声明为 private 的方法、变量和构造方法只能被所属类访问,并且类和接口不能声明为 private。
声明为私有访问类型的变量可以通过类中公共(public修饰)的 getter 方法被外部类访问。
private 访问修饰符的使用主要用来隐藏类的实现细节和保护类的数据
3. 相关问题
3.1 访问控制和继承
注意以下方法继承的规则:
-
父类中声明为 public 的方法在子类中也必须为 public。
-
父类中声明为 protected 的方法在子类中要么声明为 protected,要么声明为 public,不能声明为 private。
-
父类中声明为 private 的方法,不能够被继承。
3.2 构造器的访问权限
构造器的访问权限可以是以上四种权限中的任意一种:
-
采用 private:一般是不允许直接构造这个类的对象,再结合工厂方法(static方法),实现单例模式。注意:所有子类都不能继承它。
-
采用包访问控制:比较少用,这个类的对象只能在本包中使用,但是如果这个类有static 成员,那么这个类还是可以在外包使用;(也许可以用于该类的外包单例模式)。
注意:外包的类不能继承这个类; -
采用 protected :就是为了能让所有子类继承这个类,但是外包的非子类不能访问这个类;
-
采用 public :对于内外包的所有类都是可访问的;
注意: 构造方法有点特殊,因为子类的构造器初始化时,都要调用父类的构造器,所以一旦父类构造器不能被访问,那么子类的构造器调用失败,意味子类继承父类失败!
参考链接: