编译器对父子类同名变量和同名方法的处理

编译器对父子类同名变量和同名方法的处理

带有override的情况

先看个例子,猜猜会输出什么?

class Base {
int count = 2;

public void display() {
System.out.println("Base : " + this.count);
}
}

class Derived extends Base {
int count = 20;

@Override
public void display() {
System.out.println("Derived : " + this.count);
}
}

public class Main {
public static void main(String[] args) {
Base bd = new Derived();
System.out.println(bd.count);
bd.display();
Derived d = new Derived();
Base d2b = d;
System.out.println(d2b.count);
}
}

输出的结果为:

2
Derived : 20
2

Tip: 
编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。

原因如下: 
编译器在处理方法和成员变量时存在区别。在子类没有重写父类的方法时,编译器会将父类中的方法copy到子类中,如果子类复写,则无法copy。对于实例变量而言却不存在这样的现象,子类定义的同名变量无法覆盖父类的同名变量,就如同上面“2和20”的例子,两个都存储了,正是由于变量和方法之间的处理存在这样的区别,所以对于一个引用类型的变量而言:

  • 访问变量时,按照声明该变量时的类型(编译时类型)
  • 访问方法时,按照实际引用的对象的类型(运行时类型)

因此,对于System.out.println(bd.count);而言,bd的编译时类型为Base,因此就会输出Base的count,也就是2;对于bd.display();而言,调用的是方法,bd的运行时类型为Derived,因此也就会调用了子类的display()方法。System.out.println(d2b.count);同理,会输出编译时类型Base的count了

不带有override的情况

看完了上面的例子,别跟这个情况搞混了,看看下面代码,猜猜输出的是啥

class Father {
public void foo(Object o) {
System.out.println("Father.foo()");
}
}

class Son extends Father{
public void foo(String s) {
System.out.println("Son.foo()");
}
}

public class Main {
public static void main(String[] args) {
Son son = new Son();
son.foo(new Object());
}
}

别说这个也是“Son.foo()”,注意这个是overload!不同不同于上面的例子,son从父类中继承到了foo(Object o)方法,son会根据传入的参数不同而决定使用哪个方法。对于本例,传入的是Object,因此son会使用继承的foo方法,而非自己的。因此它的正确输出如下:

Father.foo()

_

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值