我刚刚学习java,在学到第三章:面向对象 的时候遇到了这个问题:父类引用去访问子类对象。以下是我写的一个例子。
public class Test1 {
public static void main(String[] args) {
A1 a = new A2(1,33);
a.print();
System.out.println(a.getId());
System.out.println(a.getAge());
/*A2 a1 = (A2)a;
a1.print1();
System.out.println(a1.getId());
System.out.println(a1.getAge());*/
}
}class A1 {
private int id = 1, age = 1;

A1() {
System.out.println("xixi");
}

A1(int id, int age) {
this.id = id;
this.age = age;
//System.out.println("1");
}

public int getId() {
//System.out.println("z");
return id;
}

public int getAge() {
//System.out.println("z");
return age;
}

public void print() {
System.out.println(getId() + "+" + getAge());
}
}class A2 extends A1 {
private int id, age;

A2(int id, int age) {
this.id = id;
this.age = age;
}

public int getId() {
System.out.println("y1");
return id;
}

public int getAge() {
System.out.println("y2");
return age;
}

public void print1() {
System.out.println(getId() + "-" + getAge());
}
}
当我不重写getId()和getAge()两个方法时,输出的结果是 0 0;
重写后输出的结果是 1 33。希望高手出手帮忙解决。谢谢!

解决方案 »

  1.   

    不重写getId()和getAge()两个方法时,a.getId()和a.getAge()调用的是A1的方法,而A1里面两个私有变量初始值都是1,所以输出结果应该是1 1(不是0 0!)。重写getId()和getAge()两个方法时,a.getId()和a.getAge()调用的是A2的方法,输出的是A2里面两个私有变量的值,由构造函数初始化为1和33。注意,不管重不重写getId()和getAge()两个方法,A2的构造函数并没有调用A1的A1(int id, int age)构造函数,而是隐式地调用A1(),所以A1的两个私有变量初始值都是1。
      

  2.   

    id和age是两个私用属性子类是不会继承的。所以在A2中其实是看不到A1中的这两个私有属性,只能看到自已(A2)中的这两个属性。
    当A2重写getId()和getAge()这两个方法后,由于里氏替换原则会调用A2他本身的这两个方法。而A2的这两个方法访问的是A2的id和age这两个属性。
    当A2没有重写getId()和getAge()这两个方法后,调用的是从父类(A1)继承过来的这两个方法。而这两个方法访问的是A1的getId()和getAge()这两个属性。
    记住new A2(1,33)是将1和33赋给了A2自身定义的id和age属性并不是A1的。在A2中根本不知道A1中这两个属性的存在。
      

  3.   


    A1 a=new A2(1,33)
    //此句话实现2个作用:
    //1.实例化A2的一个对象调用A2的构造方法
    //2.子类A2向父类A1转型
    //当对象发生向上转型时自动调用子类覆写过的方法
    //父类的两个私有属性的getter方法(getId()和getAge())
    //子类覆写了父类的getId()和getAge()方法原理明白了,此题就清楚了。
    当你覆写(重写)getId()和getAge()两个方法时,输出的结果是1和33.调用子类A2的两个方法
    当你不覆写(重写)getId()和getAge()两个方法时,调用的方法是父类A1的两个方法。因此输出结果是1和1
      

  4.   

    public class Test1 {
     public static void main(String[] args) {
     A1 a = new A2(1,33);
     //a.print();
     System.out.println(a.getId());
     System.out.println(a.getAge());
     /*A2 a1 = (A2)a;
     a1.print1();
     System.out.println(a1.getId());
     System.out.println(a1.getAge());*/
     }
    }class A1 {
     private int id=1, age=1; A1(){} A1(int id, int age) {
     this.id = id;
     this.age = age;
     //System.out.println("1");
     } public int getId() {
     //System.out.println("z");
     return id;
     } public int getAge() {
     //System.out.println("z");
     return age;
     } public void print() {
     System.out.println(getId() + "+" + getAge());
     }
    }class A2 extends A1 {

     
     
     
     private int id=2, age=2; A2(int id, int age) {
    super(id,age); } public int getId() {
     //System.out.print("y1");
     
     return id;
     } public int getAge() {
     //System.out.print("y2");
     return age;
     } public void print() {
     System.out.println(getId() + "-" + getAge());
     }
     
    }
    如果这样是不是就调用A1的A1(int id, int age)构造函数,而且A2就把2给赋值了呢