簡體   English   中英

如果公共成員訪問了私有成員,則不要繼承它

[英]Don't inherit private member if it's accessed by public member

很抱歉,我可能一直都在問這個問題,但我搜尋了一下,卻找不到足夠的答案。

如果公共成員/方法正在訪問私有成員/字段,如何禁用它們的繼承?

所以考慮一下:

public class A {
    private MemberA a = new MemberA();

    public void foo(TypeA x) {
    a.methodCall(); //access to a
    }
}

public class B extends A {
    private MemberB b = new MemberB();

    public void foo(TypeB x) {
    b.methodCall(); 
    }
}

如果您點擊調試器,您將看到B擁有一個類型為MemberA的字段a。 這符合Java規則,因為如果公共成員有權訪問私有成員,它將被繼承。 但是在B中,“ a”是沒有用的,並且僅占用內存-即使您沒有在B的構造函數中實例化它,因為B稱為它的超級構造函數,並且必須在A中實例化,因為a對a的使用非常多。

需要為A和B使用相同的方法名稱,並且它們必須是公共的,但是由於它們做的根本不同,而且還共享公共邏輯B,因此需要從A繼承。

因此,基本上,我需要知道如何同時重載和重寫方法。 或重復代碼。 該怎么辦?

這種情況(類中有您不想繼承的數據成員)稱為“拒絕的請求”反模式 ,通常意味着您的繼承關系是錯誤的。 而不是讓B擴展A,您需要兩個都獨立實現的接口C。 如果確實要共享重要的實現,那么也許可以引入A和B可以共享的抽象基類。

或者,也可能是MemberA和MemberB( 不是A和B )共享公用接口(或抽象類),稱為“ Member”,包括methodCall()。 然后你可以做

public class A {
  protected Member myMember;  // sounds like an Austin Powers movie...

  // in the constructor
  myMember= new A();
}

而在類B中,構造函數則改為:(或使用DI等)。

  myMember = new B();

不需要重載的 foo() ,調用myMember.methodCall()

不知道您的問題,很難說這種方法或@Ernest的方法是否更好。 無論哪種情況,您都在尋找共同的功能,而這可能是相同的工作量。

暫無
暫無

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

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