簡體   English   中英

為什么調用將父類作為參數的方法調用,而不是將子類作為參數獲取的方法?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM