![](/img/trans.png)
[英]Java wrap a child class method such that the parent method gets called first and then calls child class method
[英]Why the method that gets the Father class as a parameter is called and not the method that gets the child class as a parameter?
我有一個名為A的類,以及一個名為B的類,它擴展了A.使用一些方法來理解多態行為,我遇到了一個奇怪的情況。
public class Main {
public static void main(String[] args){
B b = new B();
A a = b;
b.f1(a);
}
}
public class A {
.
.
.
public void f1(A a){
if(a instanceof B)
f1((B)a);
else
System.out.println("Nothing");
}
.
.
.
}
public class B extends A {
.
.
.
public void f1(B b){
System.out.println("B::f1(B)");
}
.
.
.
}
我期望A類中的f1首先被調用(因為a是A類型)實際發生了。 然后我預料到行f1((B)a); 被稱為,因為a是B的一個實例。到現在為止,一切都按預期進行。 但是,我認為下一個將被調用的方法是B類中的f1(B)。相反,A類中的f1(A)被反復調用,導致堆棧溢出異常。 為什么不叫B級的f1(B)? B的一個實例是調用者,參數被強制轉換為B類。
f1(A a)
是A
類的實例方法。 它不了解A
的子類方法。 因此,它不能調用void f1(B b)
類的B
。 因此, f1((B)a)
void f1(A a)
再次執行void f1(A a)
。
如果要調用f1(B b)
,則必須在類B
的實例變量上調用f1
:
public void f1(A a){
if(a instanceof B) {
B b = (B)a;
b.f1(b);
} else {
System.out.println("Nothing");
}
}
你的A級不知道B類存在於某個地方且具有B.f1(B b)函數。 實際上f1(A a)和f1(B b)是兩個不同的功能。 您想要實現的目標應該以不同的方式完成:
public class A {
//...
public void f1(A a) {
System.out.println("Nothing");
}
//...
}
public class B {
//...
public void f1(B a) {
// this is different function, because of another parameters
}
public void f1(A a) {
if(a instanceof B)
f1((B)a);
else
super.f1(a);
}
//...
}
代碼必須強制轉換方法的調用者,如下所示:
public class A {
public void f1(A a){
if(a instanceof B)
((B) this).f1(a);
else
System.out.println("Nothing");
}
}
在您的代碼中,您只是在轉換參數。 這樣做會導致對同一個類的同一方法進行遞歸調用。
如果您轉換調用者而不是通知JVM您要調用子類上的方法,那么您可以立即退出該方法。
重要說明請注意,根據參數調用調用者的強制轉換可以生成類強制轉換異常,例如在以下上下文中:
B b = new B();
A a = new A();
a.f1(b);
您無法確定在B對象上調用接收B參數的方法f1 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.