父类代码:
package pa;
public class Base_eb1947
{
public int k;
public Base_eb1947(int k)
{
this.k=k;
System.out.println("call this f_method");
}
protected void prn()
{
System.out.println("the number of k is:"+k);
}
public static void main(String []args)
{
Base_eb1947 k =new Base_eb1947(8);
k.prn();
}
}
不同包下子类代码:
package pb;
import pa.Base_eb1947;
public class Sub_eb1947 extends Base_eb1947
{
int k;
public Sub_eb1947(int k)
{
super(k);
System.out.println("call this s_method");
}
}
class ExtendsDemo_eb1947
{
public static void main(String args[])
{
Sub_eb1947 test = new Sub_eb1947(7);
test.prn();
}
}
运行结果:
pb/Sub_eb1947.java:19: 错误: prn() 在 Base_eb1947 中是 protected 访问控制
test.prn();
^
1 个错误
但是看教材上,是写着:”protected修饰的成员变量可以被本类、类的子类(可以在不同包下)和同一个包的其他类访问”的呀。
其实这个问题问法是错的,在子类中是可以访问另一个包中父类中的protected方法,能问出这样的问题,多半是在不同包的子类中创建了父类对象,通过父类对象去调用protected方法,结果发现编译不通过,所以才会萌生这样的疑问。
正确的访问方式:
1. super.method() //protected
2. 创建子类对象instance,通过instance.method()访问
表面理解
为什么子类中不能访问另一个包中父类中的protected方法?
一般我们问这个这个问题呢,其实是没有明白protected权限到底controll了什么,都知道protected修饰的成员变量和方法可以被包外的子类访问到,这里被包外子类访问实质并不是可以在子类中通过创建父类对象来访问这个protected方法, 而是可以通过创建子类对象来访问的。这也可以说是protected权限对包外访问时的一种限制,在包内则可以像public那样可以在任意地方访问。
产生这个问题的主要是我们把在包内访问的方式理解强加到了包外。其实我们又可以转换问题为什么跨包访问某个类的protected方法必须通过继承呢?答案很简单,通过继承呢,子类就可以获得了父类方法的地址信息并把这些信息保存到自己的方法区,这样就可以通过子类对象访问自己的方法区从而间接的访问父类的方法(重写的话,就直接访问子类自己重写后的方法)。