2013-01-08 46 views
7

我有一個類(Base)和一個InfoBase類型的字段來存放一些信息。基地的專業化(Ext)需要持有附加信息(InfoExt)。 因此Ext將一個InfoExt分配給Base.info。然而,我遇到問題時 基地替換信息,因爲它會分配info = new InfoBase()因此 InfoExt的其他信息丟失。如何擴展基本成員字段?

因此,我創建了基地(變體A)中的abstract void assign()。在這個 案例信息需要被輸出到InfoExt每次它在外部使用。

在變式B中,我還額外創建了abstract InfoBase info()

       variant A      variant B 
+----------------+ +---------------------------+ +----------------------------+ 
| InfoBase  | | Base      | | Base'      | 
|----------------| |---------------------------| |----------------------------| 
| + name: String | | + info: InfoBase   | | + abstract InfoBase info() | 
|    | | + abstract void assign() | | + abstract void assign() | 
|    | |       | |       | 
+----------------+ +---------------------------+ +----------------------------+ 
     ^     ^       ^
      |      |        | 
      +      +        + 
+----------------+ +---------------------------+ +----------------------------+ 
| InfoExt  | | Ext      | | Ext'      | 
|----------------| |---------------------------| |----------------------------| 
| + id: int  | | + void assign() {   | | + InfoExt info    | 
|    | |  info = new InfoExt(); | | + InfoBase info() {  | 
|    | | }      | |  return info;   | 
+----------------+ +---------------------------+ | }      | 
                | + void assign() {   | 
                |  info = new InfoExt(); | 
                | }      | 
                +----------------------------+ 

class InfoBase { 
    public String name; 
} 

abstract class Base { 
    abstract public void assign(); 
    abstract InfoBase info(); 
} 


class InfoExt extends InfoBase { 
    public int id; 
} 

class Ext extends Base { 
    public InfoExt info; 

    @Override InfoBase info() { return info; } 

    @Override public void assign() { info = new InfoExt(); } 
} 

這是一個普通的情況,如何處理它?變體A/B有沒有 的缺點?

如何在Base中提供一個信息字段,該子類可以用來存儲擴展信息?

謝謝您的考慮

+0

我不確定如果明白你的問題,你說問題是'info'總是需要被鑄造,但是你沒有解決A或B的問題。 –

+0

In B:Ext'.info是InfoExt類型的,因此Ext'可以在沒有強制轉換(從InfoBase到InfoExt)的情況下以InfoExt的形式訪問它。我希望這能夠澄清它。 –

+0

我認爲你的問題是你要求對象提供信息,而不是告訴他們該怎麼做 - http://pragprog.com/articles/tell-dont-ask – SpaceTrucker

回答

0

,如果你有信息庫的一個子類,它的數據將主要訪問,你應該在基類中改變的特性「信息」類型InfoExt。

在不久的將來,也許你會有InfoBase的其他任何子類有不同的數據和行爲,那麼你怎麼做呢?在這種情況下,我建議你使用GOF的Bridge-Pattern,它會幫助你解決它。

1

也許像這樣的東西是你在找什麼?

abstract class Base { 
    private InfoBase info; 

    abstract public void assign(); 

    protected void setInfo(InfoBase info) { 
     this.info = info; 
    } 

    public InfoBase getInfo() { 
     return info; 
    } 
} 

class Ext extends Base { 
    private InfoExt info; 

    @Override 
    public InfoExt getInfo() { 
     return info; 
    } 

    @Override 
    public void assign() { 
     info = new InfoExt(); 
     setInfo(info); 
    } 

} 

這將使基地服務InfoBase對象,而分機可以起到InfoExt

0

如果你正在尋找一種方式,以避免鑄造,這可能工作(使用泛型):

public abstract class Base<T extends InfoBase> { 
    protected T info; 

    public T info(){ 
     return info; 
    } 

    public abstract void assign(); 
} 


public class ExtBase extends Base<InfoExt> { 

    @Override 
    public void assign() { 
     info = new InfoExt(); 
    } 
} 

信息將會型InfoExt的子類ExtBase的。例)

ExtBase b = new ExtBase(); 
b.info() // Returns Type InfoExt 
0

我不完全理解你的問題,但在這裏不用小費:

通常情況下,實例化基地的子類時,你就必須每個子類中的第二種方法的其特定的語句(初始化或類似的東西)被子類重寫。因此,例如,每個子類將使用特定的InfoBase子類實例化info

之後,分機應該只覆蓋在需要信息庫的具體行爲方式,鑄造信息到合適的班級。

這是最簡單的設計。由於我不知道代碼的複雜性,所以我無法給你一個更具體的解決方案;但你也可以考慮使用適配器模式,策略或狀態(當然取決於問題來解決)。