簡體   English   中英

僅在某些子類中重寫相同的方法,如何避免重復?

[英]Overriding same method in only some child classes, how to avoid duplication?

我正在使用一個基類,目前有5個子類。 其中三個孩子的某些功能相似,但並非全部。 我無法介紹新的層次結構,因為在子級1,2,3中重復了某些方法,而在2,3,4中重復了一些方法。

我如何才能最好地避免在所有3個子級中覆蓋方法並重復代碼。

當您不想使用多重繼承時,也可以使用composition

將通用代碼放入一個特殊的類中,然后將該類的實例添加到需要代碼的那些子類中。 然后,您可以導航到功能或將調用包裝到訪問方法中(內聯)。

創建一個混合類,並使具有共同方法的子代也從中繼承。 例如:

class Base {
  public:
    virtual commonFunction() { /* default implementation */ };
}; 

class Mixin {
  public:
     virtual notSoCommonFunction() { /* default implementation */ };
};

class D1 : public Base {
  public:
     virtual commonFunction() { /* override implementation */ };
};

class D2 : public Base, public Mixin {
  public:
     virtual commonFunction() { /* override implementation */ };
     virtual notSoCommonFunction() { /* override implementation */ };
};

class D3 : public Base, public Mixin {
  public:
     virtual commonFunction() { /* override implementation */ };
     virtual notSoCommonFunction() { /* override implementation */ };
};

因此,所有類D1,D2,D3都實現(並可選地重寫)commonFunction,但只有D2和D3實現(並可選地重寫notSoCommonFunction)。

您可以為每個函數的不同實現添加一個帶有protected方法的新中間類。 然后在子類中重寫原始基類中的方法,並從此新的中間類中調用適當的protected方法。

class Base {
    public void foo() { /* ... */ }
    public void bar() { /* ... */ }
}

class Middle extends Base {
    protected void foo1() { /* ... */ }
    protected void foo2() { /* ... */ }
    protected void bar1() { /* ... */ }
    protected void bar2() { /* ... */ }
}

class Child1 extends Middle {
    // Use default foo()
    public void bar() { bar1(); }
}

class Child2 extends Middle {
    public void foo() { foo1(); }
    public void bar() { bar2(); }
}

class Child3 extends Middle {
    public void foo() { foo2(); }
    // Use default bar()
}

或者您可以探索策略模式 有時,HAS-A關系比IS-A是更好的選擇。 當然,我不知道您的問題是否允許引入模式

上面的大多數答案都談論使用新類,但是我使用的方法調用了該類的許多其他方法,並且還使用了一些類實例變量。 如果我使用mixin或編寫新類,則將無法實現該方法。

如果您需要訪問該類的其他成員,則可以使用模板化的mixins,將this指針static_cast到適當的類型:

template<class T>
class M1Mixin {
public:
   int m1() {
     return static_cast<T*>(this)->some_value;
   }
};


class Base {
public:
  int some_value;
  ...
};

class A : public Base, M1Mixin<A> {
  ...
};

它不漂亮,但是可以用。

在獲得滿意答案之前,代碼審查可以等待,對嗎? 涼。 :-)

另一個可行的解決方案如下:

假設基類名為MyBaseClass,子類為ChildClass1至ChildClass5,並且您要復制的函數如下所示:

public int foo(Object args)
{...}

現在,您可以做的是使用靜態方法創建一個單獨的類(稱為“ HelperFunctions”或類似的類):

public static int fooHelper(BaseClass theClass, Object args)
{insert duplicated code here}

然后在要調用該輔助函數的類中包含foo函數。

這有一些優點:

  1. 您不是要創建新對象或更改類型層次結構。 由於助手功能是靜態的,因此您無需任何新對象即可調用它。
  2. 您仍然可以調用該類的方法,因為您要傳入BaseClass類型的對象,因此可以像在類內部那樣調用它的方法。

上面的大多數答案都談論使用新類,但是我使用的方法調用了該類的許多其他方法,並且還使用了一些類實例變量。 如果我使用mixin或編寫新類,則將無法實現該方法。

我不確定我是否理解問題所在。 至少在我的解決方案中,您正在傳遞對象,因此您可以調用任何方法並訪問所需對象上的實例變量。 您要訪問的實例變量或方法是私有的,這樣您就無法在類外部訪問它們的問題嗎? 在這種情況下,您可以通過將helper函數聲明為朋友函數來輕松解決此問題(有關如何使用它們的教程,只需使用Google“ c ++朋友函數”)

暫無
暫無

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

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