JAVA修饰符Protected的访问权限控制
-
Java四大访问权限
| 自身 | 同包类 | 外包子类 | 外包非子类 |
private | √ | | | |
default | √ | √ | | |
protected | √ | √ | √ | |
public | √ | √ | √ | √ |
其他访问权限都很容易理解,就是protected有一些模糊不清,下面具体解释说明,同时附带了个demo验证,主要解释,可以结合看一下。
-
protected访问权限问题
初始基类的protected成员:
1.所谓可见就是可以通过初始基类或继承了初始基类的子类的实例访问初始基类的protected成员,访问的都是初始基类的protected成员。如果某个子类重载了protected成员,它以及它的子类的实例访问的都是这个类重载的protected成员,这个子类变成某种意义上新的初始基类(对于它以及它的子类来说),这个类的父类不能再通过这个类及其子类的实例访问protected成员(指向的protected成员不同了)。
2.与初始基类同包的所有的类对初始基类的protected成员都可见,访问的都是初始基类的protected成员。这也就意味着,与初始基类同包的无关类,都可以通过初始基类或继承了初始基类的子类(包括外包子类)的实例访问初始基类的protected成员。
3. 外包的子类可以通过自身的实例或者自身的子类(可以不与自身同包)的实例访问初始基类的protected成员,不能通过其父类(包括最上层的初始基类)的实例访问基类的protected成员。
-
JAVA代码实践
以下demo通过基类Base重载Object的clone()方法来演示protected对应的访问权限情况。也就是说在这个demo中,对于Base及其子类,clone()这个方法的初始基类是Base,不再是Object,访问的也都是Base的protected成员clone()。
demo分成包括三个不同的包(test1,test2,test3),六个不同的类(Base,Tes1,Father1,Father2,Test2,Child),验证所有场可能的情况下,不同类对protected成员的访问情况是否与前面所说的一致。
如果有遗漏的情况或者错误,请留言告知。具体请看demo中的注释,建议直接copy到IDE中看一下,更容易理解些。
package demo.test1;
import demo.test2.Father1;
import demo.test3.Child;
/**
* @description: 初始基类
* @author: Dafengsu
* @date: 2019/7/26
*/
public class Base implements Cloneable {
/**
* 重新实现clone 方法,对于Base的子类,clone的方法就都来源于Base
* @return
* @throws CloneNotSupportedException
*/
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
/**
* 初始基类中自然所有子类的clone方法都可见
* @param args
* @throws CloneNotSupportedException
*/
public static void main(String[] args) throws CloneNotSupportedException {
Base base = new Base();
Father1 father1 = new Father1();
Child child = new Child();
base.clone();
father1.clone();
child.clone();
}
}
package demo.test1;
import demo.test2.Father1;
import demo.test3.Child;
/**
* @description: 与初始基类同包的测试类,与初始基类Base无继承关系
* @author: Dafengsu
* @date: 2019/7/26
*/
public class Test1 {
/**
* 与初始基类同包的测试类,对于Base的所有子类的clone方法也都可见
* @param args
* @throws CloneNotSupportedException
*/
public static void main(String[] args) throws CloneNotSupportedException {
Base base = new Base();
Father1 father1 = new Father1();
Child child = new Child();
base.clone();
father1.clone();
child.clone();
}
}
package demo.test2;
import demo.test1.Base;
import demo.test3.Child;
/**
* @description: 中继类(与初始基类Base不同包,继承初始基类Base)
* @author: Dafengsu
* @date: 2019/7/26
*/
public class Father1 extends Base {
/**
* 初始基类的外包子类可以通过自身实例(base)和自身子类的实例(child)来访问Protected成员
* @param args
* @throws CloneNotSupportedException
*/
public static void main(String[] args) throws CloneNotSupportedException {
Base base = new Base();
Father1 father1 = new Father1();
Child child = new Child();
// base.clone(); //编译失败,子类中不可以通过父类的实例来访问Protected成员
father1.clone();
child.clone();
}
}
package demo.test2;
import demo.test1.Base;
import demo.test3.Child;
/**
* @description: 与中继类(Father1)同包的初始基类的外包子类,继承初始基类Base
* @author: Dafengsu
* @date: 2019/7/26
*/
public class Father2 extends Base {
/**
* 外包子类,对其父类(Base),及其同包的兄弟类(都继承Base)及其子类的clone方法都不可见
* @param args
* @throws CloneNotSupportedException
*/
public static void main(String[] args) throws CloneNotSupportedException {
Base base = new Base();
Father1 father1 = new Father1();
Child child = new Child();
//以下全部编译失败
// base.clone();
// father1.clone();
// child.clone();
}
}
package demo.test2;
import demo.test1.Base;
import demo.test3.Child;
/**
* @description: 与中继子类同胞的测试类,与初始基类Base无继承关系
* @author: Dafengsu
* @date: 2019/7/26
*/
public class Test2 {
/**
* 编译失败,与中继子类(Father1)同包的测试类,对初始基类(Base),中继子类(Father1),中继
* 子类的子类(Child)的clone方法都不可见
* @param args
* @throws CloneNotSupportedException
*/
public static void main(String[] args) throws CloneNotSupportedException {
Base base = new Base();
Father1 father1 = new Father1();
Child child = new Child();
//以下全部编译失败
// base.clone();
// father.clone();
// child.clone();
}
}
package demo.test3;
import demo.test1.Base;
import demo.test2.Father1;
/**
* @description: 子类(与初始基类Base和中继类都不同包),继承中继类Father1
* @author: Dafengsu
* @date: 2019/7/26
*/
public class Child extends Father1 {
/**
* 子类对初始基类(Base)以及其直接父类(Father1)的clone方法都不可见,但是可以通过
* 自身的实例(child)访问Protected成员
* @param args
* @throws CloneNotSupportedException
*/
public static void main(String[] args) throws CloneNotSupportedException {
Base base = new Base();
Father1 father1 = new Father1();
Child child = new Child();
// base.clone();
// father1.clone();
child.clone();
}
}