方法使用超类引用变量重载/覆盖Java子类对象 [英] Method overloading/overriding in Java subclass object with superclass reference variable

查看:94
本文介绍了方法使用超类引用变量重载/覆盖Java子类对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  class A {
void m1(A a){System.out.print(A);}
}
B类A {
void m1(B b){System.out.print(B);}
}
C类扩展B {
void m1(C c){ System.out.print(C);}
}

public class d {

public static void main(String [] args){

A c1 = new C(); C c2 = new C(); c1.m1(c2);

}}

此代码的输出为 'A'



但是如果我修改A类:

  class A {
void m1(C a){System.out.print(A);}
}

那么输出为'C'。请解释这段代码是如何工作的?

解决方案

(你使这个更加混乱,分离这些可能有助于简化它。)



的类型, c1 A 。因此,当编写出要调用的方法签名时,编译器只能查看 A 中声明的方法。



所以在第一种情况下,编译器将调用 m1(A);在第二种情况下,编译器将调用 m1(C)



m1(A)方法不会被覆盖,因此实际上 c1 的执行时类型是不相关的。 p>

在第二种情况下, m1(C) C ,因此 C 中的实现被调用,因为 c1 的执行时类型为




  • 根据方法目标和参数表达式的编译时类型,在编译时确定
    重载解析()。

  • 该方法签名的实现(覆盖)基于执行时的目标对象的实际类型。


 class A{
 void m1(A a) {System.out.print("A");}
  } 
  class B extends A{
  void m1(B b) {System.out.print("B");}
  } 
  class C extends B{
  void m1(C c) {System.out.print("C");}
  }

 public class d {

 public static void main(String[] args) {

  A c1 = new C(); C c2 = new C();c1.m1(c2);

 }}

Output of this code is 'A'.

But if I modify class A as:

 class A{
 void m1(C a) {System.out.print("A");}
  }

then the output is 'C'. Could somebody please explain how is this code working?

解决方案

(You've made this more confusing than it needs to be by using the same inheritance hierarchy for both the parameter types and the implementation. Separating those would probably help to simplify it in your mind.)

The type of c1 is A. Therefore when working out which method signature it's going to call, the compiler can only look at methods declared in A.

So in the first case, the compiler is going to call m1(A); in the second case, the compiler is going to call m1(C).

Now in the first case, the m1(A) method is never overridden, so actually the execution-time type of c1 is irrelevant.

In the second case, m1(C) is overridden by C, so the implementation in C is called because the execution-time type of c1 is C.

So remember:

  • Overload resolution (which method signature is called) is determined at compile-time, based on the compile-time types of both the method target and the argument expressions
  • The implementation of that method signature (overriding) is based on the actual type of the target object at execution time.

这篇关于方法使用超类引用变量重载/覆盖Java子类对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆