6

これは初心者の質問かもしれませんが、Wheel プロパティの複製を抽象クラスにリファクタリングしながら、Part タイプへの明示的なキャストを維持する標準的な方法はありますか? FastCarWheel が SlowCar に配置されないようにする必要があり、このようなプロパティが多数あるとします。

abstract class Car {}

class FastCar : Car
{
    public FastCarWheel Wheel { get; set; }
} 

class SlowCar : Car
{
    public SlowCarWheel Wheel { get; set; }
} 

abstract class WheelPart {}

class FastCarWheel: WheelPart {}

class SlowCarWheel: WheelPart {}

このタイプのシナリオでは、このタイプの重複を許可するのが一般的ですか? ジェネリックを利用することを考えていましたが、問題を動かしているように見え、このように動作する追加のプロパティごとに悪化します。

abstract class Car <P>
    where P : Part
{
    protected abstract P Wheel { get; set; }
}

ありがとう

4

5 に答える 5

1

FastorSlow ポリシーを使用すると、特定の車種に適切なホイールを配置するのに役立つと思います(Carとの両方Wheelがポリシーに依存しており、Carオブジェクトには、たとえば、ホイールのプライベートな集合体があります)。

于 2009-04-23T18:18:07.123 に答える
1

このソリューションはポリモーフィックではありませんが、基本クラス レベルでの可視性が必要な場合は、唯一のオプションになる可能性があります。

abstract class Car
{
    private CarWheel wheel;
    public CarWheel Wheel
    {
        get { return wheel; }
        protected set { wheel = value; }
    }
}

class FastCar : Car
{
    public new FastCarWheel Wheel
    {
        get { return base.Wheel as FastCarWheel; }
        set { base.Wheel = value; }
    }
}

class SlowCar : Car
{
    public new SlowCarWheel Wheel
    {
        get { return base.Wheel as SlowCarWheel ; }
        set { base.Wheel = value; }
    }
}

基本クラスの処理が多すぎるかどうかを評価する必要がある場合があります。クラスを多くの小さなクラスに分割することで、問題を解決できる場合があります。一方で、やむを得ない場合もあります。

于 2009-04-23T18:18:53.487 に答える
1

抽象クラスの代わりに、ICar を作成し、Car をそのように定義します。

interface ICar
{
   IWheel Wheel {get; set;}
}

class FastCar: ICar
{
   FastWheel fastWheel;
   IWheel Wheel
   {
      get { return fastWheel; }
      set
      {
          if (value is FastWheel) fastWheel = (FastWheel)value;
      }    
   }         
}

class SlowCar: ICar
{
   SlowWheel slowWheel;
   IWheel Wheel
   {
      get { return slowWheel; }
      set
      {
          if (value is SlowWheel ) slowWheel = (SlowWheel )value;
      }    
   } 
}

class FastWheel: IWheel {}
class SlowWheel: IWheel {}
于 2009-04-23T18:19:31.363 に答える
1

あなたの目標は、クライアント コードがプロパティを WheelPart として取得できるようにすることですが、それを特定のサブクラスとしてのみ設定することを許可しているように見えるため、いくつかのオプションがあります。残念ながら、どちらもあまりきれいではありません。

まず、間違ったタイプが設定されていると、ランタイム エラーがスローされる可能性があります。

    public abstract class Car
    {
        public abstract WheelPart Wheel { get; set; }
    }

    public class FastCar : Car
    {
        private FastWheel _wheel;
        public override WheelPart Wheel
        {
            get { return _wheel; }
            set
            {
                if (!(value is FastWheel))
                {
                    throw new ArgumentException("Supplied wheel must be Fast");
                }
                _wheel = (FastWheel)value;
            }
        }
    }

しかし、他のタイプのホイールが例外をスローすることはクライアント コードにとって非常に不明確であり、コンパイラーのフィードバックは得られないため、私はこれを行いません。

それ以外の場合は、必要な型が非常に明確になるように、プロパティの Getter と Setter を分離できます。

    public abstract class Car
    {
        public abstract WheelPart Wheel { get; }
    }

    public class FastCar : Car
    {
        private FastWheel _wheel;
        public override WheelPart Wheel
        {
            get { return _wheel; }
        }

        public void SetWheel(FastWheel wheel)
        {
            _wheel = wheel;
        }
    }

これはクライアントにとってより明確であり、ゲッターを基本の WheelPart クラスとして絶対に公開する必要がある場合は、より優れたソリューションです。

于 2009-04-23T18:32:51.503 に答える
0

ホイール インターフェイス (IWheel) を定義します。

public interface IWheel
{
}

FastCarWheel と SlowCarWheel のインターフェースを実装します。

public class FastCarWheel : IWheel
{
}

抽象クラスは次のようになります。

abstract class Car 
{
 public IWheel Wheel { get; set; }
}

Car のサブクラスは、選択した Wheel の実装を自由に使用できます。

FastCar fastCar = new FastCar();
fastCar.Wheel = new FastCarWheel();
于 2009-04-23T18:14:50.330 に答える