2016-10-06 10 views
0

注:完全な質問を読むことを検討する前に、それを閉じるよりも編集を提案する方がよいかもしれません。継承/再利用機能/複数の親からのプロパティ

更新はい、私はC#は多重継承を許可していません知っているが、オフコースのシナリオを次のように実質的に必要なそのいくつかの時間は、そう案内してください、どちらかそれは必要ではない理由や、それが達成できたか


ある子供の異なるクラスの機能/メンバーを継承/再利用する必要があります。私は私が必要とする実際のクラスはMovableSingleCellHurdleMovableMultiCellHurdleStationarySingleCellHurdleStationaryMultiCellHurdle

あるクラス

abstract class Hurdle 
{  
    public virtual void setPositionInCells(){somecode_sp();} 
    public virtual void OnHit(){somecode_h();} 
} 

を持っていますが、C#で、私はこれだけ

class SingleCellHurdle: Hurdle 
{ 
public int CellNumber; 
public override void setPositionInCells(){ base(); somecode_sp1();} 
} 
class MultipleCellHurdle: Hurdle 
{ 
public int[] CellNumbers; 
public override void setPositionInCells(){ base(); somecode_sp2();} 
} 

class MovableHurdle: Hurdle 
{ 
public float HitForce; 
public override void OnHit() { base(); somecode_h1();} 
} 
class StationarHurdle: Hurdle 
{ 
public override void OnHit() { base(); somecode_h2();} 
} 

を行うことができますが、私は次の操作を行うにもこだわっています

class MovableSingleCellHurdle: MovableHurdle, SingleCellHurdle 
{ 
    public override void OnHit() { base();} 
    public override void setPositionInCells() { base();} 
    public int getLastHitForce() 
    { 
     return HitForce; 
    } 
    public int getLastPositionCells() 
    { 
     return CellNumber; 
    } 
} 

私がする必要があるのはなぜiが再び本当のクラスのsetPosition()OnHit()のコードを複製する必要はないことを、ある

私がやっている現在、何を

そのは私が私を加えることができないので、全く継承/再利用ではありません必要な構造の上に

私はこの数年前に学んだはずだったが、残念なことに、この継承のシナリオを特別に対象とする記事/ブログは見つかりませんでした。

この質問は投票に値すると思いますが、それでもOKですが、私にも案内してください。私がそれを完全に間違っているとすれば、私はどのようなアプローチをとるべきでしょうか?または、最高のoopの慣行を使用してこのシナリオを処理することについて完全に説明している記事

+1

まず、C#では複数のクラスからの継承を許可していません。あなたの 'MovableSingleCellHurdle'は無効です。また、 'base()'は無効です。代わりに、おそらく 'base.baseMethod()'を意味するでしょう。 – haim770

+1

継承の代わりに作曲を見ましたか? – FacticiusVir

+0

@FacticiusVir、私はそのレベルで貧しい人々のために作っているに違いない。コンポジション/継承の良いコンセプト、あなたが私のように見えたか、どうすればいいのかを教えてください。 – Sami

答えて

0

C#では多重継承をサポートしていません。

class Hurdle { ... } 
class SingleCellHurdle : Hurdle { ... } 
class MultipleCellHurdle : Hurdle { ... } 
class MovableSingleCellHurdle : SingleCellHurdle { ... } 
class MovableMultipleCellHurdle : MultipleCellHurdle { ... }  
class StationarySingleCellHurdle : SingleCellHurdle { ... } 
class StationaryMultipleCellHurdle : MultipleCellHurdle { ... } 

このような関係を持つクラスが比較的少ない場合は、明らかにこれは実用的です。あなたが持っているより多くの関係が指数関数的に成長します。

+0

また、私は 'MovableSingleCellHurdle:MovableHurdle'や' MovableMultipleCellHurdle:MovableHurdle'である。はい、それはオプションの1つですが、とても無力感を感じる – Sami

0

この場合、継承を使用することはできません。継承を使用することはできません。

理由はLSP(Liskov Substitution Principle)に基づいています。

LSPについてより明確になると、おそらくbreak LSP as explained hereになります。しかし、それだけで学者です。あなたはマイレージに基づいてそれを無視したり勉強したりすることができます。

解決方法はおそらく委任です。このように、これらのクラスにあなたデリゲートの呼び出し、

class MovableSingleCellHurdle 
{ 
    private MovableHurdle mh; 
    private SingleCellHurdle sch; 

次:

まず、あなたはが持っている、このような単純なクラスと豊かなもの、との関係を必要とします

public void OnHit() 
    { 
     mh.OnHit(); 
     // or: sch.OnHit(); 
    } 

mehtodにパラメータがある場合はそれらを渡し、何かを返す場合は次のように返します。

public int SumAndFloor(double a, double b) 
    { 
     return internalDelegateClass.SumAndFloor(a, b); 
    } 

このパターンは、より単純なオブジェクトを利用してオブジェクトを構成するため、合成と呼ばれます。

内部メソッドを呼び出すという事実はdelegationです。

さらに、コンストラクタを使用してオブジェクトを構築する必要があります。これは、constructor injectionと呼ばれます:

public MovableSingleCellHurdle(MovableHurdle mh, SingleCellHurdle sch) 
    { 
     this.mh = mh; 
     this.sch = sch; 
    } 
+0

このケースでは、継承がliskovを壊すとは思わない。提供された情報があれば、より派生していないインスタンスが必要な、より派生したクラスインスタンスを使用できない理由はありません。 –

+0

はい、いいと思いますが、私はデリゲートと一緒にそのタイプの作曲についてもっと読んで、実際にそれを解決します、それは必要な答えだと思います。 – Sami

+0

@ rory.ap私は同意する、LSPが違反しているという兆候はない。しかし、この推論は後ろ向きです(私たちが見るものはLSPに違反しないと言います)。要点は、すべてのケースでLSPに違反していないことを証明する必要がありますが、これらのケースが何であるかはわかりません。だから私は**おそらく**と言いました。正確に言うと、 'somecode_h1()'が何をしているのかわかりません。 LSPに違反している可能性はありますが、証明できません。 – pid

関連する問題