What is displayed when the following is executed? class Parent{
   private void method1(){
     System.out.println("Parent's method1()");
   } 
  public void method2()
  {
    System.out.println("Parent's method2()");
    method1();
  } 
} class Child extends Parent{
  public void method1(){
    System.out.println("Child's method1()");
  }   public static void main(String args[]){  Parent p = new Child();
  p.method2();
  }} Choices:a. Compile time error b. Run time errorc. prints : Parent's method2()          Parent's method1()d. prints : Parent's method2()          Child's method1() 答案是C但是我们把题改一下,
class Parent{
   private void method1(){
     System.out.println("Parent's method1()");
   } 
  public void method2()
  {
    System.out.println("Parent's method2()");
    method1();
  } 
} class Child extends Parent{
  public void method1(){
    System.out.println("Child's method1()");
  }   public static void main(String args[]){  Child p = new Child();//改变了这里  p.method2();
  }} 应该选什么? 也是C!我们再改一下:
class Parent{
   public  void method1(){  //change here
     System.out.println("Parent's method1()");
   } 
  public void method2()
  {
    System.out.println("Parent's method2()");
    method1();
  } 
} class Child extends Parent{
  public void method1(){
    System.out.println("Child's method1()");
  }   public static void main(String args[]){  Parent p = new Child();
  p.method2();
  }} 这次终于是答案D了,我们再改
:
class Parent{
   public  void method1(){  //change here
     System.out.println("Parent's method1()");
   } 
  public void method2()
  {
    System.out.println("Parent's method2()");
    method1();
  } 
} class Child extends Parent{
  public void method1(){
    System.out.println("Child's method1()");
  }   public static void main(String args[]){  Child p = new Child();//change here
  p.method2();
  }} 也是答案D,我这里是运行过的结果,可是不理解为什么,那个高手跳出来解释一下?参考贴:
http://community.csdn.net/Expert/topic/3490/3490386.xml?temp=.3488581

解决方案 »

  1.   

    private 方法能被覆盖吗?不能吧不过不注意还是会错的
      

  2.   

    原题,在main中只有p.method2();
    怎么结果有两行?
    c. prints : Parent's method2()          Parent's method1()
    没有调用method1()的语句嘛
      

  3.   

    第一个:因为parent类的method1方法是private的,所以child类的method1没有复写parent的method1方法。而调用的时候,因为对象 Parent p = new Child(); 所以 p.method2(); 会把方法upcast给Parent类处理:)  第二个:基本同第一个。因为method1还是没有被复写。第三个:Parent的method1终于是public了,所以被Child的method1复写。第四个:基本同第三个。好像说的不是很清楚:)
    不过可以参考Thinking In Java的相关章节,那里写得相当清楚
      

  4.   

    对于多态,其实说白了,就是在运行期判断某个对象的具体类型。所以在本例中,无论是Parent p = new Child()还是Child p = new Child(),最终在调用p.method2()的时候,实际上都是把p所指的对象当作Child类来处理的。所以大家可以看到前两种和后两种结果都分别是一样,用Parent p = new Child()还是Child p = new Child()对结果不会产生任何影响。当然,正如losen所讲,本例还涉及到继承中的重写问题,于是需要更多思考。对于后面两种存在继承的情况,其实仔细想想并没有什么,在method2中调用method1,其实隐含了this关键字,这个是动态加上去的。我就不多讲了吧。
      

  5.   

    其实你也可以从这个角度理解:对于那些在子类中没有显式重写的父类方法,在子类中其实都隐含了一份从父类继承下来的拷贝。在本例中我们调用的method2就在此列。注意在前两种情况,父类中由于method1是private的,所以在编译期method2中对method1的引用就被inline成那个private的方法,所以不在多态的范畴。
      

  6.   

    to 大胃:
    好久不见了。
    请将“编译期method2中对method1的引用就被inline成那个private的方法” 再解释一下?我是这么理解的:对于
    class Parent{
       private void method1(){
         System.out.println("Parent's method1()");
       } 
      public void method2()
      {
        System.out.println("Parent's method2()");
        method1();
      } 
    }
    在被继承时,可被继承的方法public void method2()其实已经是:
    public void method2()
    {
        System.out.println("Parent's method2()");
        System.out.println("Parent's method1()");
    }一会反编译看看。
      

  7.   

    寒这道题目,可怜的我没注意method1是private的,靠!
      

  8.   

    Hi! 其实我想要表达的就是你的意思。在Parent类被编译的时候,method2()中有一行调用method1(),这个method1是private的,所以编译器把这个method1的内容直接inline到method2()中,也就是可以理解成拷贝到method2中,替代原先对method1的调用。所以就成了你说的那个样子:
    public void method2()
    {
        System.out.println("Parent's method2()");
        System.out.println("Parent's method1()");
    }这样因为Child继承自Parent,所以对于这个public的method1,由于没有显式的继承(重写),自然也就隐含的继承下来一份拷贝啦。
      

  9.   

    纠正一个bug:我是说“所以对于这个public的method2,由于没有......”,不是“method1”。
      

  10.   

    Java 编程思想里的典型题,可参考Java编程思想
    1.由于父类里的方法是private的,故在子类中写的方法,则不能对父类的进行覆盖.又由于在父类中,只能掉用自己的方法,或是在子类中被重写的方法。但是由于父类中的方法是私有的,所以子类中定义的method1()是自己扩展出来的方法,所以对父类来说是不可见的,故父类掉用的就是自己的method1方法。2.同理3.由于父类中的方法是公有的,所以在父类中掉用方法它会首先去考虑掉用被子类重写的父类方法。4.同理。以下是我个人总结的编译器执行顺序:
    1.进入主类.
    2.先把所有的类的成员变量置上初值(引用类型的为null 基本类型的为0 bool类型的为false)
    3.从public class 里面找是否有静态成员变量的初始化,如果有静态成员变量的初始化则先执行静态成员变量的初始化。
    4.如果静态成员变量,初始化的是对象的,话那么则掉用实例化该对象的类。进入类体里首先看该类里有没有静态成员变量初始化,如果有则先掉用,然后是普通成员变量初始化。
    5.最后才是构造方法。
    注意静态的成员变量只能初始化一次!
    详细信息可参见Tingking in java