java子类成员变量与父类重名问题解释

来源:互联网 发布:小米6首选网络类型 编辑:程序博客网 时间:2024/05/20 17:26

我们都知道子类继承父类时,会继承所有的成员变量和成员方法,前提是有访问权限,若为private修饰或者default修饰却在不同包就不会继承(这里有争议的一点是有人说是时继承了但不能访问,有人说根本就没继承,博主也没有研究过,这个问题不重要,反正不能调用就对了)。先看下面一个正常的例子,熟悉一下正常的继承特性

class Parent{    public int age=30;    public void print1(){        System.out.println("parent print1:"+age);    }    public void print2(){        System.out.println("parent print2:"+age);    }}class Child extends Parent{    //public int age=10;    @Override    public void print2(){        System.out.println("child print2:"+age);    }}public class ParentChildTest {    public static void main(String[] args) {    Parent p=new Parent();    Child c=new Child();    Parent pc=new Child();    System.out.println("p.age"+p.age);    System.out.println("c.age"+c.age);    System.out.println("pc.age"+pc.age);    System.out.println();    System.out.print("p. ");    p.print1();    System.out.print("p. ");    p.print2();    System.out.println();    System.out.print("c. ");    c.print1();    System.out.print("c. ");    c.print2();    System.out.println();    System.out.print("pc. ");    pc.print1();    System.out.print("pc. ");    pc.print2();    }}

p为父类对象,c为子类对象,pc为一个用子类实例化的父类对象(实现向上转型)
输出结果:

p.age30
c.age30
pc.age30
p. parent print1:30
p. parent print2:30
c. parent print1:30
c. child print2:30
pc. parent print1:30
pc. child print2:30

可以看到,
c. parent print1:30
c. child print2:30
子类继承了父类的age属性和print1方法,并且覆写了print2方法,这两个方法都调用了age属性,print1调用的自然是父类中的age属性,而print2中调用的是父类中的属性还是子类中继承下来的属性暂且不去深究,因为这两个属性根本上来说是一样的。

下面开始进入重名这个问题
我们把上述代码中的注释打开

class Parent{    public int age=30;    public void print1(){        System.out.println("parent print1:"+age);    }    public void print2(){        System.out.println("parent print2:"+age);    }}class Child extends Parent{    public int age=10;    @Override    public void print2(){        System.out.println("child print2:"+age);    }}

可以看到父类子类里面都是一个叫age的属性,那么现在的输出结果会怎么样呢?

p.age30
c.age10
pc.age30

p. parent print1:30
p. parent print2:30

c. parent print1:30
c. child print2:10

pc. parent print1:30
pc. child print2:10

首先通过 对象名.成员变量 的方式直接取得的属性以类名为原则。若是Parent类,就取得该类中的属性,反之亦然。从pc.age30可以看出来子类实例化向上转型并没有覆盖原有父类的属性,所以可以得出继承无法覆盖成员变量,只能覆盖方法。父类与子类的成员相互独立,相互隐藏。至于c中调用从父类继承的print1方法并没有指向自己类中的age,而指向父类中的age,不难解释。因为没有覆写的方法,从父类继承下来,可看作编译器会自动帮你加上如下代码(以print1举例)

class Child extends Parent{    public int age=10;    @Override    public void print2(){        System.out.println("child print2:"+age);    }    public void print1(){        super.print1();    }}

自动去调用了父类中的print1,所以自然也指向了父类中的age。

总结,继承只能覆盖方法,而不能覆盖成员变量,若有同名变量,则相互独立,直接获取时依据对象类型,调用时依据方法定义在哪个类中。

原创粉丝点击