簡體   English   中英

Java繼承:創建子類實例時如何調用超類方法?

[英]Java Inheritance: How to invoke super class method when subclass instance is created?

我在最近的一次采訪中被問到這個問題。 尋求幫助。

  • A 類具有從構造函數觸發的 foo() 方法。
public class A {

    public A() {
        foo();
    }

    public void foo() {
        System.out.println("In foo method in class A");
    }
}

B 類覆蓋 A 類中的 foo 方法。

public class B extends A {

    @Override
    public void foo() {
        System.out.println("In foo method in class B");
    }
}

現在,如果我們創建類 B 的實例,B 中的 foo() 方法將被調用。

A a = new B();
prints: "In foo method in class B"

問題:假設我們擁有類 A,它是 jar 文件 (abc.jar) 的一部分,我們如何確保類 B 何時被實例化 A.foo() 被調用而不是覆蓋 B.foo()?

狀況:

  1. 想象一下,jar 被共享給其他用戶,我們不能破壞客戶端代碼,因為我將方法標記為 private/final。

  2. 同樣從 B 類調用 super.foo() 也不是一個選項,因為我們不擁有 B 類並且不能限制用戶。

public class A {

    public A() {
        fooInternal();
    }

    public void foo() {
        fooInternal();
    }

    private final void fooInternal() {
        System.out.println("In foo method in class A");
    }
}

您不能讓它調用A.foo() ,因為該方法已被覆蓋。 你只能讓它調用A.foo()調用的方法,並且不能被覆蓋。

這里更重要的一點是你永遠不應該從構造函數調用可覆蓋的方法。

將 A 的foo方法標記為final 這是唯一的方法。

為了仍然允許 B 在初始化時也獲得 ping,解決方案是一個兩階段的構造:A 的構造函數調用最終的 foo() 方法,但作為 foo() 方法的一部分,foo2 或 subfoo 或其他任何方法你想調用它,也被調用,並且該方法在 A 中定義為一個 noop(什么都不做)。

通常這樣的最終 init() 樣式的方法也應該是私有的。 基於共同的邏輯:“init”操作也是一個概念,外部代碼可能希望在某個任意的稍后時間點第二次調用的可能性有多大? 不可能,這就是為什么它應該是私有的。 一旦你這樣做了,那么私有方法本質上就是最終的,所以它會解決這個問題:

class A {
    public A() {
        init0();
    }

    private final init0() {
        // do stuff here - subclasses won't stop you.
        init();
    }

    // B can override this if it wants.
    protected void init() {}
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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