protected这个修饰符,各大参考书都会这样说:访问权限为类内,包内和子类,所以在父类中定义的方法和成员变量若是为protected修饰的,是能够在不一样包中的子类进行访问的,示例代码以下:spa
1 package cn.tedu.object.a; 2 3 public class A { 4 5 protected void m(){ 6 System.out.println("A m~~~"); 7 } 8 9 }
1 package cn.tedu.object.b; 2 3 import cn.tedu.object.a.A; 4 5 public class B extends A { 6 void callM() { 7 m(); 8 super.m(); 9 B b = new B(); 10 b.m(); 11 } 12 }
如上代码所示,class B继承了class A,可是两个类位于a、b两个不一样的包中,此时class B能够直接访问class A中的protected修饰的方法。一共有三种方法访问:code
第一种为第7行,直接调用;对象
第二种为第8行,加super关键字;其实前两种是等效的。blog
第三种为第九、10行,实例化一个对象进行调用。继承
那么问题来了,若是说在b包中新建一个class C,而且有以下代码,会报错吗?class
1 package cn.tedu.object.b; 2 3 import cn.tedu.object.a.A; 4 5 public class C extends A { 6 7 void callM() { 8 m(); 9 super.m(); 10 B b = new B(); 11 b.m(); //The method m() from type A is not visible 12 } 13 14 }
会报错!那为何会报错呢?import
由于b.m()这种调用属于子类对象调用,并非子类调用。变量
这个是很是须要引发注意的。所以,当建立子类对象调用父类的protected成员变量时,必需要注意:子类对象和子类是对应的!object
经过这个例子其实也能够看出来,当一个包外子类继承保护成员时,该成员在这个子类内实际上变为私有。权限
事实上,除了以上三种调用父类protected成员变量的方法外,其他都是会报错的!
包括用超类实例去访问。代码以下:
1 package cn.tedu.object.b; 2 3 import cn.tedu.object.a.A; 4 5 public class B extends A { 6 7 void callM() { 8 A a=new A(); 9 a.m(); //The method m() from type A is not visible 10 } 11 12 }
一样的,会报错!所以,能够获得结论:
包外子类有权访问超类成员,它指子类继承该成员,然而,这并不意味着包外子类可以使用超类实例的引用访问该成员。