`

【解惑】真正理解了protected的作用范围

阅读更多

      一提到访问控制符protected,即使是初学者一般都会很自信的认为自己在这方面的理解没有问题。那好,我们提一个问题出来看看.....

 

问题提出:

   请看下面两端代码,其中包B中的猫和鼠都继承了动物类。

//代码1:包A中有一个动物类
package testa;
public class Animal {
	protected void crowl(String c){
		System.out.println(c);
	}
}
//代码2:包B中有两个类——猫类和鼠类
package testb;
import testa.Animal;
class Cat extends Animal{
	
}
class Rat extends Animal{
	public void crowl(){
                crowl("zhi zhi"); //没有问题,继承了Animal中的protected方法——crowl(String)
	        Cat cat=new Cat();
                cat.crowl("miao miao"); //wrong, The method crowl(String) from the type Animal is not visible
	}
}

           既然,猫和鼠都继承了动物类,那么在鼠类的作用范围内,看不到猫所继承的crowl()方法呢?

 

症结所在:

       protected受访问保护规则是很微妙的。虽然protected域对所有子类都可见。但是有一点很重要,子类只能在自己的作用范围内访问自己继承的那个父类protected域,而无法到访问别的子类(同父类的亲兄弟)所继承的protected域。 说白了就是:老鼠只能叫"zhi,zhi"。即使他能看见猫(可以在自己的作用域内创建一个cat对象),也永远无法学会猫叫。

       也就是说,cat所继承的crowl方法在cat类作用范围内可见。但在rat类作用范围内不可见,即使rat,cat是亲兄弟也不行。

       另外: 这就是为什么我们在用clone方法的时候不能简单的直接将对象aObject.clone()出来的原因了。

 

      总之,当B extends A的时候,在子类B的作用范围内,只能调用本子类B定义的对象的protected方法(该方法从父类A中继承而来)。而不能调用其他A类对象的protected 方法

分享到:
评论
3 楼 鲁曼1991 2017-09-19  
说的都有道理,protected只能被同一级包的类所调用
2 楼 ningzhiyuan 2015-10-13  
同意二楼的看法
1 楼 rxy006 2014-01-06  
博主你好,关于你在上文中提到的“子类只能在自己的作用范围内访问自己继承的那个父类protected域,而无法到访问别的子类(同父类的亲兄弟)所继承的protected域”,我有一些不同的看法。在上面的例子中,Rat类无法访问Cat类的crowl方法,我觉得,这是因为Cat类并没有覆盖从Animal类继承得来的crowl方法,所以Rat类中cat.crowl()这句,实际上是对Animal类中crowl方法的调用,而Animal类中的crowl方法被声明为protected,但Rat类和Animal类又属于不同的包,所以会出现crowl方法方法不可见的现象。我试验过,对于上面的例子,如果把Rat类和Animal类放在同一包中,Cat类仍在另一包中(此时需要把Cat类声明为public),就不会出现crowl方法不可见的现象。以上都是我的一些想法,如有误,还望博主指正。

相关推荐

Global site tag (gtag.js) - Google Analytics