2013-01-08 5 views
7

私はクラス(Base)といくつかの情報を保持するタイプのInfoBaseのフィールドを持っています。 Baseの特殊化(Ext)は、追加情報(InfoExt)を保持する必要があります。 したがって、ExtはInfo.ExをBase.infoに割り当てます。しかし、 ベースは、info = new InfoBase()を割り当てているので、Infoを置き換えると問題に遭遇しました。したがって、 InfoExtの追加情報は失われています。基本メンバーフィールドを拡張する方法は?

したがって、abstract void assign()をベース(バリアントA)に作成しました。この のケース情報は、Extで使用されるたびに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に情報フィールドを提供するにはどうすればよいですか?あなたはそれのデータはほとんどアクセスされるInfoBaseの1つのサブクラスを持っている場合

あなたはInfoExtに基本クラスにプロパティ「情報」の種類を変更する必要があり、ご検討

+0

あなたの問題を理解しているかどうかわからないのですが、問題は「情報」が常にキャストされる必要があると言われましたが、AまたはBのどちらでも問題は解決しませんでした。 –

+0

In B:Ext'.info InfoExt型であるため、Ext 'はキャストなしでInfoExtとしてInfoExtにアクセスできます(InfoBaseからInfoExtへ)。これが明確になることを願っています。 –

+0

あなたの問題は、オブジェクトに情報を要求して、何をすべきかを伝えていないと思います。http://pragprog.com/articles/tell-dont-ask – SpaceTrucker

答えて

0

いただきありがとうございます。

の場合、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); 
    } 

} 

これは、extがInfoExtを提供することができますしながら、ベースは、InfoBaseオブジェクトにサービスを提供できるようになります。

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(); 
    } 
} 

情報は、サブクラスExtBase用タイプInfoExtのものであろう。例)私は完全にあなたの問題を理解するが、ここで先端を行くしません

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

通常、基本サブクラスをインスタンス化するとき、あなたは第二の方法ではその特定のステートメントを実行し、各サブクラスを持っているでしょう(初期化など)をサブクラスでオーバーライドします。したがって、たとえば、各サブクラスは、の情報を具体的なのInfoBaseサブクラスでインスタンス化します。その後

内線は右のみのクラスに情報を鋳造し、InfoBase特定の動作が必要なメソッドをオーバーライドする必要があります。

これは最もシンプルなデザインです。私はあなたのコードの複雑さを知らないので、私はあなたにもっと具体的な解決策を与えることができません。アダプター・パターン、ストラテジーまたは状態の使用を検討することもできます(もちろん、解決する問題に応じて)。

関連する問題