Java继承:向上转换子类
我已经阅读了文档和其他问题,但有一些向上转换的案例确实让我感到困惑 我举了这个例子,虽然前3个案例经过一点思考后非常简单,但最后4个案例让我感到困惑 很明显,我对演员阵容有些不了解Java继承:向上转换子类,java,inheritance,casting,upcasting,Java,Inheritance,Casting,Upcasting,我已经阅读了文档和其他问题,但有一些向上转换的案例确实让我感到困惑 我举了这个例子,虽然前3个案例经过一点思考后非常简单,但最后4个案例让我感到困惑 很明显,我对演员阵容有些不了解 class A { public static void p (Object o) { System.out.println(o); } public void m1 (A a) { p("m1(A) in A"); } public v
class A {
public static void p (Object o) { System.out.println(o); }
public void m1 (A a) { p("m1(A) in A"); }
public void m1 () { m1(new B());}
public void m2 (A a) { p("m2(A) in A");}
public void m2 () { m2(this);}
public void m3 (B b) { m2(this); }
}
class B extends A {
public void m1 (B b) { p("m1(B) in B");}
public void m2 (A a) { p("m2(A) in B");}
public void m2 (B b) { p("m2(B) in B");}
public void m3 (B b) { super.m1(b);}
}
public class Main {
public static void main(String[] args) {
A a = new B(); // Instance of class B casted to A
B b = new B(); // Instance of class B
// 1. prints "m1(A) in A"
b.m1();
// 2. prints "m2(A) in B"
b.m2();
// 3. prints "m2(A) in B"
a.m2();
// 4. prints "m1(A) in A"
a.m3((B)a);
}
}
例1:
我希望这里能打印出B中的m1(B)
B继承A,因为没有B.m1()
,它调用A.m1()
,后者调用m1(B)
。既然我们是从B调用,为什么它调用A.m1(B)
,而不是B.m1(B)
我期望A.m1()->B.m1(A),而不是A.m1()->A.m1(B)
例2:
因为4在一个“中给出了”m1(A),所以我在这里也期望得到同样的结果,因为对我来说,流程似乎是一样的
看看示例1,我期望A.m2()->A.m2(A),而不是A.m2()->B.m2(A)
例3:
bb.m2()代码>在B中打印m2(A)
我希望m2(A)在A中是m2(A),因为A被铸造成A
。为什么它调用B.m2(A)
例4
它调用B.m3()
,如果它强制转换为A
。为什么?我希望它调用A.m3()
,因为它已经被浇铸了示例1:调用m1(新的B())代码>在类A
中A
不知道子类的任何实现细节(例如B
),因此它只知道A.m1(A)
示例2:您可以添加一个简单的System.out.println(this.getClass())
显示此
的类。它将显示此
的类型为$B
。您在B
上调用了该方法,并且B
知道该方法m2(B)
,因此调用了一个方法。
例3:与例5的原因相同。
示例4:它被称为B.m3()
,后者依次调用super.m1(B)代码>。这将调用super方法A.m1(A)
,因为B
扩展了A
。它无法调用B.m1(B)
,因为它显式地调用了super
。如果A
中没有足够的方法,您将得到一个编译器错误
更新
示例1和示例2之间的差异:
在例1中b.m1()
正在调用类A
的方法m1()。因为在调用m1()
时,编译器只知道类型是A
,而不是B
。假设您只能看到a
类型的变量,那么您只能看到a
的方法。因此,随后调用m1(new B())
导致调用A
方法。没有B
可供编译器调用它的方法。
在示例2中是b
类型的变量b
,因此编译器可以查看A
的所有方法和b
的所有方法。正因为如此,编译器知道方法B.m2(B B)
,并且可以在随后的m2(this)
调用中调用它。您能否更具体地说明问题本身,您对它感到困惑的是什么,以及为什么?不仅仅是在代码中的注释中。@Stultuske你是对的,我还单独添加了问题,试图进一步解释它们。这很长,而且有点难理解。我建议您删除所有您已经理解的内容,只留下您想要解释的代码部分,以及一点您自己的推理。除此之外,你问的问题还不错。@CoffeeNinja完成了,简化了,并试图让它变得更清晰。这是一个很好的问题,关于继承容易被误解的事情。例如,下面提交的唯一答案(以及投票结果)是错误的。虽然我写了另一个答案,但我不能提交,因为它很快就被搁置了。对不起,我仍然不知道4之间的区别。五,。我怎么知道4在类A中被调用,而5和6在类B中被调用?虽然m1(新的B())确实在类A中被调用,但B的重写方法仍然是首选的,而不是A的原始方法。A中的this
的类型。m1()实际上是B(在示例1中)