请看下面程序:
package com.msn.spaces.bryantd001.packageone;public class SuperClass{
    protected void show(){
        System.out.println("This is a protected-access method in the super class in the package one.");
    }
}package com.msn.spaces.bryantd001.packagetwo;
import com.msn.spaces.bryantd001.packageone.*;public class OverridingTest extends SuperClass{
    //是否覆盖了超类的方法啊????
    public void show(){
        System.out.println("This is a real overriding method in the sub class in the package two.");
}    public static void main(String[] args){
        //SuperClass superObj=new SuperClass();
        SuperClass superObj=new OverridingTest();
        superObj.show();//这里报错!!!说show()方法在packageone的SuperClass中具有protected访问权限,因此无法调用。我昏~~~在子类中不是已经将这个方法覆盖了吗???
    }
}
通过实验,这两个文件要是不写在不同的包中就没有问题。但是protected访问权限不是包和子类吗???所以子类的同名方法应该覆盖了超类的show()方法啊!!所以我觉得superObj.show();应该是调用的子类的方法啊!!为什么不行呢??

解决方案 »

  1.   

    肯定重写了
    不过, 要知道 protected方法 在包外的子类中,只能以子类或者子类的子类的引用访问
      

  2.   

    1、覆盖只是相对而言,并不是真的覆盖了。父类的方法还是父类的方法,并不会因为子类重写了他的方法而导致他自己的方法不见了。估计楼主混淆了这点了。
    2、superObj.show();这个调用的不是子类的方法,这个是他自己(SuperClass )的方法,你创建的是SuperClass 的对象而不是OverridingTest的对象。所以这里你这样调用是不行的,因为他们不在一个包里。
      

  3.   

    楼上的这位朋友,我创建的是OverridingTest对象,只是用超类的引用指向了它。请你注意,这个问题是多态问题,如果你感兴趣,你不妨把我的程序稍作修改,放在一个包内运行,是没有问题的。也就是说,我这么做就是在利用多态的机制。
    而真正的问题是:这种多态机制为什么在包外就不起作用了呢?还有你说的第一点,如果子类覆盖了超类的方法,理论上说对于子类就是屏蔽了,当然这不意味着子类就无法访问被屏蔽的这个同名方法,比如如果被覆盖的超类方法是public,我们仍然可以在子类中利用super.的方法来访问。我并没有混淆这个概念,谢谢~~曾曾胡朋友,我想知道为什么“protected方法在包外的子类中,只能以子类或者子类的子类的引用访问”呢?难道我上面说得多态机制在有包的情况下就丧失了吗?
      

  4.   

    楼主这个问题是protected的访问权限问题,而也是否覆盖无关。
    在这里,你的父类对象在父类所处的包外被创建,所以它“看不见”自己类中定义的那个protected方法,这个方法只能被它的子类的实例调用,父类自己的实例不能调用它。
      

  5.   

    确切的讲,superObj.show();
    在编码时确实是在调用自己的show()方法.
    如楼上讲的,子类和父类不在一个包中是不能调用的.当然子类的确也覆盖了父类的show()方法
    SuperClass superObj=new OverridingTest();
    是后期绑定.(运行时动态绑定)
    LZ看看<<Java编程思想>>的"运行期类型鉴定"和"多形态"的章节,
    自然就明白了.
      

  6.   

    晕,你怎么还没明白啊?动态绑定跟有没有包没有关系,但是,如果一个方法在访问上就有问题的话,还谈什么绑定?你把那protected方法改成public不就行了?
      

  7.   

    你把我的程序改成这样,让两个类在一个包下运行:
    class SuperClass{
        protected void show(){
            System.out.println("This is a protected-access method in the super class.");
        }
    }public class OverridingTest extends SuperClass{
        public void show(){
            System.out.println("This is a real overriding method in the sub class.");
        }    public static void main(String[] args){
            SuperClass superObj=new OverridingTest();
            superObj.show();
        }
    }您能解释一下这样为什么就没问题吗?
      

  8.   

    楼主精神可嘉,这么晚还在研究这个问题啊。解释你上面代码能正常工作的原因在于,JAVA的protected是允许包内访问的,而这个方法又被子类重写了,所以根据多态调用规则,当然是调用子类的方法。楼主:我知道你的初衷是要一个多态方法,但前提是,你要设法让你的代码通过编译,编译都通不过,代码不能运行,谈何多态?
      

  9.   

    http://blog.csdn.net/f_acme/archive/2006/02/28/611878.aspx
      

  10.   

    前些天遇到了跟楼主一模一样的问题,很多人都说是静态和非静态,以及多态的问题,其实是权限问题,我的感觉是,protected这个关键字的含义并不只是同一个包和子类可见那么简单,下面两段话可供参考protected modifer means the method is visible in both the same package and subclass.if the subclass isn't in the same package, in the class body and out of main method body,the protected method is visible. Notice main method is very special.查了一下文档,测试了一下,是package权限问题。默认和protected都是package权限,即父类、子类在同包下,在子类中的父类实例才能调用它自身的protected方法,否则是没有权限的。-----基本的java知识,这回记住了,又学到了一点儿!
      

  11.   

    LZ加油,建议回头看看:《Java编程思想》"隐藏实现","运行期类型鉴定"和"多形态"的章节,
      

  12.   

    protected访问权限在以往的教学过程中老师都是这样讲到的:protected具有包访问权限和包外子类访问权限,也就是对应楼上的兄弟说的这句话:protected modifer means the method is visible in both the same package and subclass其实问题也就在这里,在不同包的子类中如果重写了超类的同名方法,那么在子类的包中就不能再像在一个包中那样,根据多态调用规则:超类引用指向子类对象,在调用同名方法,即调用子类的方法,这下记住这个规则了。谢谢各位帮我解释,我也明白了多态是一个运行时候的概念范畴,我现在正在看《Thinking in java》。之前已经学习了一本java书,赫赫。大家一起努力!
      

  13.   

    protected权限不能跨package?
    疑惑了,swing中很多Model类的protected方法被我们自己写的类extands后都要覆盖的呀~~
      

  14.   

    说了半天Notice main method is very special.是正解。
      

  15.   

    换汤不换药:
    package com.msn.spaces.bryantd001.packageone;public class SuperClass{
        
        protected void show(){
            System.out.println("This is a protected-access method in the super class in the package one.");
        }
        
        public void call(){
    show();
    }
    }
    package com.msn.spaces.bryantd001.packagetwo;
    import com.msn.spaces.bryantd001.packageone.*;public class OverridingTest extends SuperClass{
        
        public void show(){
            System.out.println("This is a real overriding method in the sub class in the package two.");
    }

    public static void main(String[] args){
            SuperClass superObj=new OverridingTest();
            superObj.call();
        }
    }
    结果调用子类方法,这是lz要得答案吧