java:protected的访问权限

问题由来

先看一段代码

class MyObject{
    
}

public class Test {
    public static void main(String[] args) {
       MyObject obj = new MyObject();
       obj.clone(); // Compile error.
    }
}

clone是Object里面一个protected的方法,protected的访问权限应该是相同的包,或者其子类。但是这里我却没办法访问到clone()方法。

问题还原Demo

新建一个父类,并且声明一个protected()的方法,申明两个子类继承父类

package protectTest.p1;

public class Father1 {

	protected void f() {}
}

package protectTest.p2;
public class Son1 extends Father1 {

}

package protectTest.p2;
public class Son2 extends Father1 {

	public static void main(String[] args) {
		Son2 son2 = new Son2();
		son2.f();
		Son1 son1 = new Son1();
		son1.f();// Compile error.
	}
}

可以看到son1编译报错:原因就是虽然都是继承Father1父类,但是兄弟之间是不可以相互访问保护的方法的。

解决问题

由此回到一开始MyObject和Test,在Test中不能调用MyObject的clone也是都是继承了父类Object,但是兄弟类之间是不可以互相访问的。

扩展了解

如果把Son2移到包P1,编译就不会报错。那是因为protected方法的访问权限是,同一个包下或者是子类,当都在同一个包p1下面的时候,son1就不会报错。

package protectTest.p1;
public class Son2 extends Father1 {

	public static void main(String[] args) {
		Son2 son2 = new Son2();
		son2.f();
		Son1 son1 = new Son1();
		son1.f();
	}
}

拓展理解

package protectTest.p2;

public class Son11 extends Father1 {

	public static void main(String[] args) {
		Father1 f = new Father1();
		System.out.println(f instanceof Father1);//true
		System.out.println(f instanceof Son11);//false
		
//		f.f();//compile error
		Son11 son11 = new Son11();
		System.out.println(son11 instanceof Father1);//true
		System.out.println(son11 instanceof Son11);//true
		son11.f();
	}
}

可以看到f中的保护方法在其他包是不可访问的,而子类son是可以访问的。

外文帮助理解

《java in a nutshell》中的一段话:

protected access requires a little more elaboration. Suppose class A declares a protected field x and is extended by a class B, which is defined in a different package (this last point is important). Class B inherits the protected field x, and its code can access that field in the current instance of B or in any other instances of B that the code can refer to. This does not mean, however, that the code of class B can start reading the protected fields of arbitrary instances of A! If an object is an instance of A but is not an instance of B, its fields are obviously not inherited by B, and the code of class B cannot read them.

参考链接

参考链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值