2

これを解決するための最良の方法は何ですか?

静的メンバーはすべてのサブクラスに対応するものであり、サブクラスに別の静的メンバーが必要ですが、名前は同じなので、vehicle.canDoを使用できます。これにより、vechicleインスタンスが実際にどのクラスであるかに応じて異なる配列が得られるはずです。

canDo配列から静的なものを削除することもできますが、同じサブクラスのすべてのインスタンスは常にcanDo配列で同じ値を持つ必要があるため、すべてのインスタンスにcanDo配列を含める必要はありません。これは、メモリの大きな浪費になります。このクラスのインスタンスが多すぎます。

class Vehicle {
    public static List<string> canDo;

    static Vehicle() {
        canDo = new List<string>(); 
        canDo.Add("go");
    }
}

class Plane : Vehicle {
    static Plane() {
        canDo.Add("fly");
    }
}

class Ship : Vehicle {
    static Ship() {
        canDo.Add("sail");
    }
}



class Main {
    static void Main(string[] args) {
        Vehicle plane = new Plane();
        Vehicle ship = new Ship();

        plane.canDo; // Contains (go, fly and sail) i want only (go and fly)
        ship.canDo; // Contains (go, fly and sail) i want only (go and sail)
    }
}
4

4 に答える 4

4

これを解決するための最良の方法は何ですか?

静的でないものに静的メソッドを乱用しないでください。そのように単純です。

静的には継承がなく、継承シナリオを持つことができるものではありません。

あなたは機能を悪用することによって戦いを戦っています-戦う価値はありません。適切なオブジェクト指向を学んでください。

于 2012-07-03T11:48:13.423 に答える
3

そのために静的変数とコンストラクターは必要ありません。基本コンストラクターを追加するだけです(これはデフォルトで実行され、: base()オプションです)。

class Vehicle {
    public List<string> canDo;

    Vehicle() {
        canDo = new List<string>(); 
        canDo.Add("go");
    }
}

class Plane : Vehicle {
    Plane() : base() {
        canDo.Add("fly");
    }
}

class Ship : Vehicle {
    Ship() : base() {
        canDo.Add("sail");
    }
}

更新:@EbenRouxのコメントに基づく-

public abstract class Vehicle {
    protected static List<string> _canDo;
    protected abstract List<string> getCanDo();
    public List<string> canDo{
        { get {
               var _cando = new List();
               _cando.AddRange(Vehicle._canDo);
               _cando.AddRange(this.getCanDo());
               return _cando;
              }
        }
    }
    static Vehicle() {
        _canDo = new List<string>(); 
        _canDo.Add("go");
    }
}

class Ship : Vehicle {
    protected static List<string> childCanDo;
    protected override getCanDo(){
        return Ship.childCanDo;
    }
    static Ship() {
        childCanDo.Add("sail");
    }
}
于 2012-07-03T11:49:40.167 に答える
3

canDoを使用して基本クラスのを非表示にすることもできることに注意してください。new

class Vehicle
{
    public static List<string> canDo = new List<string>() { "go" };   
}

class Plane : Vehicle
{
    public new static List<string> canDo = new List<string>(Vehicle.canDo);
    static Plane()
    {
        canDo.Add("fly");
    }
}
于 2012-07-03T12:00:41.930 に答える
2

canDoタイプごとにリストのインスタンスが必要です。したがって、コンストラクターを介してコレクションを渡すか、サブタイプレベルで静的にすることができます。

編集(詳しく説明する):

サブクラスインスタンスはすべて同じ「能力」を持っており、それぞれのリストにデータを入力したくないので、共有リストが必要になります。おそらく構成が必要な場所で継承を使用しています。

public abstract class Vehicle
{
    protected List<string> canDo;

    protected Vehicle(List<string> canDo)
    {
        this.canDo = canDo;
    }
}

public class Plane : Vehicle
{
    public Plane(List<string> canDo) : base(canDo)
    {
    }
}

私はList<string>どちらも使用しませんが、ビジネスに意味のあるクラスにカプセル化します(これは単なる例であることを理解していますが)。リストにデータを入力するcanDoには、サブタイプにファクトリまたはファクトリメソッドを使用できます。

これを行うには非常に多くの方法があり、快適なものを見つける必要があります。

私は代わりにスタティックを提示しましたが(あなたがそれについて尋ねていたので)、私は間違いなくこれにスタティックを使用しませんでした。

于 2012-07-03T11:46:56.730 に答える