1

次のようないくつかのクラスをセットアップしようとしています。

public abstract class AnimalBase {      
  public string SpeciesName { get; private set; }

  public AnimalBase(string speciesName) {
    this.SpeciesName = speciesName;
  }

  public abstract void CopyFrom(AnimalDefaultClass defaultVals);
}

public class Mammal : AnimalBase {
  public bool WalksUpright { get; private set; }

  public Mammal(string speciesName) : base(speciesName) {
    this.CopyFrom(new MammalDefaultClass(speciesName));
  }

  public override void CopyFrom(MammalDefaultClass defaultVals) {
    this.WalksUpright = defaultVals.WalksUpright;
  }

  public void Cripple() {
    this.WalksUpright = false;
  }
}

public class MammalDefaultClass : AnimalDefaultClass {
  public bool WalksUpright { get; private set; }

  public MammalDefaultClass(string speciesName) {
    using (var dataStore = theoreticalFactory.GetDataStore()) {
      this.WalksUpright = dataStore[speciesName].WalksUpright;
    }
  } 
}

明らかに、それは私が達成しようとしていることではありませんが、アイデアは次のとおりです。

  • 抽象ベース (動物) から継承するいくつかのクラス (哺乳類、魚、昆虫など)。
  • 各子クラスには、基本クラスで抽象として定義されたメソッドのパラメーターとして使用できる対応するクラスがあります (この場合、変更可能なデフォルト値を入力するために)。
  • これらの対応するクラス (MammalDefaultClass、FishDefaultClass、InsectDefaultClass など) はそれぞれ、共通の基本クラス (AnimalDefaultClass) から継承されます。

Animal の各クラスには異なるプロパティがあるため、これらの AnimalDefaultClass 派生物が存在しますが、定義により、どの動物に対してもそれらの値を取得できるクラスが常に存在します。

私の問題は次のとおりです。

MammalDefaultClass は AnimalDefaultClass から継承されますが、そのオーバーライドされたバージョンの CopyFrom(MammalDefaultClass) は、抽象 CopyFrom(AnimalDefaultClass) の有効なオーバーライドとして認識されません。

抽象メンバーのパラメーターとして基底クラスを指定することは可能ですか? 簡単な*回避策はありますか? それとも、この全体が間違ってレイアウトされているだけですか?

-編集: 私の解決策 - MWB と sza の提案でいくつか遊んだ後、最終的に各サブクラスに base パラメーターを使用してメソッドを実装させ、次のように入力を適切にキャストすることになりました。

public class Mammal : AnimalBase {
  ...

  // implements the abstract method from the base class:
  public override void CopyFrom(AnimalDefaultClass defaultVals) {
    this.CopyFrom((MammalDefaultClass)defaultVals);
  }

  public void CopyFrom(MammalDefaultClass defaultVals) {
    this.WalksUpright = defaultVals.WalksUpright;
  }
}

この解決策により、私は常に CopyFrom(AnimalDefaultClass) を実装する必要があります。これは、最初に基本クラスに抽象メソッドを配置するポイントでした。

4

2 に答える 2

1

したがって、MammalDefaultClass は AnimalDefaultClass のサブクラスですが、AnimalDefaultClass を受け取る関数を MammalDefaultClass を受け取る関数でオーバーライドすることはできません。

次のコード ブロックを検討してください。

public class Dinosaur : AnimalDefaultClass;
Dinosaur defaultDinosaur;

public void makeDinosaur(AnimalDefaultClass adc)
{
    adc.CopyFrom(defaultDinosaur);
}

MammalDefaultClass m;
makeDinosaur(m);

この場合、MammalDefaultClass は AnimalDefaultClass のサブクラスであるため、m を adc として makeDinosaur に渡すことができます。さらに、AnimalDefaultClass の CopyFrom には別の AnimalDefault クラスのみが必要なので、恐竜を渡すことができます。しかし、そのクラスは実際には哺乳動物であるため、恐竜ではない MammalDefaultClass が必要です。

回避策は、元の型シグネチャを取得し、引数が間違った型である場合にエラーをスローすることです (Java での配列の動作と同様)。

于 2013-07-29T16:33:40.947 に答える