2010-05-26 59 views
4

我有一個與OOP相關的問題。我有一個接口,說:OO - 繼承與裝飾問題

class MyInterface { 
    public int getValue(); 
} 

在我的項目,該接口由7個實現來實現:

class MyImplementation1 implements MyInterface { ... } 
... 
class MyImplementation7 implements MyInterface { ... } 

這些實現是由幾個不同的模塊中。對於某些模塊,MyInterface的行爲必須稍微調整。假設它必須返回實現者+1的值(爲了舉例)。我通過創建一個小裝飾者解決了這個問題:

class MyDifferentInterface implements MyInterface { 
    private MyInterface i; 

    public MyDifferentInterface(MyInterface i) { 
     this.i = i; 
    } 

    public int getValue() { 
     return i.getValue() + 1; 
    } 
} 

這樣做的工作。

這是我的問題:其中一個模塊不接受MyInterface參數,但直接MyImplementation4。原因是這個模塊需要MyImplementation4的特定行爲,而MyInterface接口本身沒有涉及它。但是,這裏有困難,這個模塊也必須在MyImplementation4的修改版本上工作。也就是說,getValue()必須返回+1;

解決此問題的最佳方法是什麼?我沒有想出一個不包含大量代碼重複的解決方案。

請注意,雖然上面的例子非常小和簡單,接口和裝飾器是相當大和複雜。

非常感謝。

回答

0

MyImplementation4中聲明getValuevirtual關鍵字。

MyImplementation4繼承一個新類,並使用override關鍵字聲明getValue函數並將其實現爲return base.getValue()+1

+1

感謝您的回答。裝飾器MyDifferentInterface非常複雜並且包含很多代碼。這個解決方案意味着我必須複製所有這些代碼。 – 2010-05-26 18:48:31

+0

OP正在使用Java語法; Java沒有'virtual'關鍵字(方法默認是虛擬的!) – 2010-05-26 19:00:59

+0

爲什麼你不能聲明一個繼承MyImplementation4的新類並且只覆蓋你必須改變返回值的方法?這聽起來很簡單。 – 2010-05-26 19:06:55

2

如果是在Java中,你可以做

class ModifiedMyImplementation4 extends MyImplementation4 
{ 
    @Override 
    public int getValue() 
    { 
     return super.getValue() + 1; 
    } 
} 

沒有代碼的重複!

+0

+1雖然當然,*最佳*選項將修復其他模塊的設計,但這可能是不可能的。 – 2010-05-26 19:01:43

+0

+1,或者如果您不想繼承,請將「MyImplementation4」的實例傳遞給構造函數,並將未更改的操作委託給該實例。 – 2010-05-26 19:17:00

+0

或者只是將一個開關添加到MyImplementation4,使其將getValue()的返回值增加1(如果設置爲true)。 – 2010-05-27 10:37:47

0

你可以嘗試這樣的:

public class MyDifferentImplementation4 extends MyImplementation4 { 
    private MyDifferentInterface mdi; 
    public MyDifferentImplementation4(MyDifferentInterface mdi) { 
     this.mdi = mdi; 
    } 
    public getValue() { 
     return mdi.getValue(); 
    } 
} 

傳遞給構造函數的MyDifferentInterface實例應包裝MyImplementation4的實例(你可以強制執行,通過使用MyDifferentInterface其構造的一個子類了MyImplementation4的實例,而不是界面)。

0

該解決方案意味着我必須 複製這些代碼

不能你把將被複制到一個抽象類MyAbstractImplementation的代碼?然後,這兩個子類可以從抽象類繼承。它所需要的只是一個抽象方法,它甚至不需要做任何事情,只需要孩子們實施。

void foo(void);

需要一個不同的行爲的孩子覆蓋方法。消費者需要接受MyAbstractImplementation類型而不是接口。 Voila,沒有代碼重複。