Java中的控制符,用来控制其他类能否访问Java中的某一方法、变量,即控制java类、方法、变量的可见性、可访问性,从而实现数据封装。Java中有两个级别的访问控制符。
类级别:控制其他类能否使用该类。有2中类型: public 和 package-private
成员级别:控制某一方法、变量的访问权限。有4种类型: public , protected, package-private, private。
首先解释一下“使用”一词到底是什么意思?对于方法,很显然就是调用;对于变量,则是指访问或者修改;而对于类,则是指继承、实例化等,也就是能否在import中导入。
需要注意的事,方法和变量的访问控制实在类级别访问的基础之后增强的,也就是先经过类级别这层控制之后,再加上成员级别的控制。通过这两个级别的权限控制,可以对Java中的类、方法、变量进行精确控制,进而实现我们想要的任何程度的数据封装。下面分别介绍着两个级别的访问控制符。
类级别:
一个类可以被声明为public,在这种情况下,这个类可以被任何其他类导入使用(但是具体到某个方法或者变量时,需考虑第二层成员级别控制)。
如果类没有控制访问描述符,则表示默认,也就是包私有(package-private),这时该类除了能在本类中使用外,还能被同一个包中的其他类使用。注意包的概念,不包括子包。
备注:如果是内部类,可以使用private修饰符。下面的讨论都针对一般类
成员级别:
成员级别可以使用类级别中的public, package-private,其意义与类级别完全一样。除此之外还可以使用private和protected。但是要注意,默认方式不能用于接口变量和方法。
private :如果某个成员被private修饰,则它只能在它所在的类中被使用( The private modifier specifies that the member can only be accessed in its own class.)。
protected: 如果用protected修饰,除了能被同一个包中的其他类(无论是否继承自该类)使用之外,还能被其他包中的子类使用。(The protected modifier specifies that the member can only be accessed within its own package (as with package-private) and,in addition, by asubclass of its class in another package.)注意接口中的变量和方法一样不能使用protected修饰符。
总结如下表:
例如,有两个包one和two,四个类如下图所示
对于Alpha这个类中的成员,其他类的访问权限如下表:
继承与访问修饰符:
继承中,子类和父类的修饰符需要遵守一些规则,具体如下:
父类方法为public,子类也必须为public
父类为protected,子类必须为protected或者public
父类中的private方法没有继承的说法。
子类继承自父类,所以父类中提供的方法接口,子类都必须提供。否则,如果我们将一个子类的对象赋给父类对象,就会出问题。如下:
public class Animal {
public String getName() { return this.name; }
}
public class Lion extends Animal {
private String getName() { return this.name; }
}
Animal lion = new Lion();
System.out.println( lion.getName() );//invalid
此时,lion声明为Animal类型,但它的实际类型是Lion。Animal类型提供了公开的getName接口,而子类却变成private,不行!!
一个疑惑
假设现在我们将一个类声明为package-private,也就是这个类只能被跟它在同一个包的类使用。那么在这个类当中,一个声明为protected或者public的方法似乎已经不是很有意义,因为默认的package-private就已经足够了,其他包中的类不能使用这个类,更不用说使用方法了,那么在实际开发中呢,到底什么样的实践才是最佳的,有待进一步研究。
猜测:
如果一个类声明为package-private则该类中的方法声明为public,protected,和package-private 效果是一样的。
总结:子类中重载的方法的访问控制符必须必父类弱,如图:
(转载请注明出处)
出处