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

我们都知道子类继承父类时,会继承所有的成员变量和成员方法,前提是有访问权限,若为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。

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

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值