public class Father { private String name; private int age; private int weight; public void eat() { System.out.println("Father is eating"); } private void run() { System.out.println("Runing...."); } public Father() { name = "zhangsan"; age = 23; weight = 60; } public static void main(String[] args) { /* * *如果子类的构造方法中对继承来自父类的变量重新赋予新的值的话,那么这样子调用的将会是子类的变量 *如果子类重新定义了和父类一样的变量的话那么这样将会输出的是父类的变量 *Father f = new Son(); *f.age f.weight */ Father f = new Son(); f.eat(); f.run(); System.out.println("。。。。。。年龄是:" + f.age + "\t" + f.weight + "\t" + f.name); // Son s = new Father();这样子会报错 } } class Son extends Father{ private int salary; public void eat() { System.out.println("Son is eating"); } public void sleep() { System.out.println("sleep ...."); } public Son() { name = "lisi"; age = 3; salary = 60; weight = 70; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
最终输出的结果
f.eat()输出的是子类中重写父类中的eat()方法
f.run()输出的是父类中的run()方法(实际上是输出的子类中的,只是因为子类中没有重写,所以看上去输出的是父类中的,实际调用的是子类的)
f.age和f.weigth输出的是子类的构造方法中重新赋值的
f.name输出的是父类中的属性
由此可以看出,父类引用指向子类对象,最终这个父类引用所拥有的变量是是子类中的(如果构造方法中没有重新赋值那就和父类中的一样,如果重新赋值了那就是子类中赋值以后的),方法也是子类中的(如果重写了就是重写之后的方法,如果没有重写的那就和父类中的一样)