【问题标题】:Java subclassing: what is the method that will get triggered?Java 子类化:触发的方法是什么?
【发布时间】:2017-05-20 16:12:32
【问题描述】:

我正在学习 Java,我得到了以下代码:

public class A {
    public void m(A a) { System.out.println("A.m:A"); }
    public void m(B b) { System.out.println("A.m:B"); }
}

public class B extends A {
    private void m(C c) { System.out.println("B.m:C"); }
    public void m(B b) { System.out.println("B.m:B"); }
}

public class C extends A {
    public static void main(String args[]) {
        A ab = new B();
        B bb = new B();
        A ac = new C();

        ab.m(ac); // My answer: A.m : A || correct
        ab.m(ab); // My answer: B.m : B || Correct answer: A.m : A
        ab.m(bb); // My answer: B.m : B || correct
        bb.m(ac); // My answer: compile error || Correct answer: A.m : A
        bb.m(ab); // My answer: B.m : B || Correct answer: A.m : A
        bb.m(bb); // My answer: B.m : B || correct
        ac.m((A)bb); // My answer: A.m : A || correct
        bb.m((B)ac); // My answer: compile error || Correct answer: run-time error [Class cast exception] --> I UNDERSTAND THIS
        bb.m((B)ab); // My answer: B.m : B || correct
    }
}

我必须在 main 函数中写出调用的结果。 如您所见,我得到的大多数答案都是错误的。 我想了解的是,当我有一个使用 子类的构造函数创建的超类的类型变量时,如何确定调用哪个类函数>?

【问题讨论】:

标签: java inheritance methods subclass


【解决方案1】:

要回答此类问题,您需要考虑三件事:

  1. 调用方法的对象的运行时类型是什么?
  2. 什么是编译时方法的参数类型?
  3. 参数转换是否会出现错误(如果有)?

回答 (1) 查看声明的右侧:abbb 的类型为 B,而 ac 的类型为 C

要回答 (2),请查看声明的左侧:abAbbBacA

要回答 (3),请查找类型转换,并与第 (1) 部分中的类型进行比较。允许将子类转换为基类,如(A)bb。但是,在同级之间进行转换(如 (B)ac)会在编译时类型让您确定您正在转换同级时​​导致编译时错误,或者在编译时类型是父级时导致运行时错误。

一旦你对 (1) 和 (2) 有了答案,并且排除了由 (3) 引起的错误,你需要查看源代码,并从 (1) 中选择与类型匹配的类的方法重载(2) 中的类。

【讨论】:

  • 非常感谢!非常详细且解释清楚:)
【解决方案2】:

上面的答案非常有道理,所以我不会重复那个用户已经说过的话。您的答案不正确的场景(除了您提到的您已经理解的场景)都与将使用子类实现创建的超类对象作为参数传递给方法m有关。

A ab = new B();
B bb = new B();
A ac = new C();

ab.m(ab); // My answer: B.m : B || Correct answer: A.m : A
bb.m(ac); // My answer: compile error || Correct answer: A.m : A
bb.m(ab); // My answer: B.m : B || Correct answer: A.m : A

在上述所有这些语句中,您实际上传递了一个A 的对象,尽管实现是子类的。因此,无需进一步混淆,您可以查找正在获取对象A 参数的方法。因为实际的对象实现只能在运行时解析。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-11
    • 2017-12-09
    • 2019-04-23
    • 2011-07-01
    • 2012-04-25
    • 1970-01-01
    • 2013-08-11
    • 1970-01-01
    相关资源
    最近更新 更多