簡體   English   中英

用作抽象方法參數的基類?

[英]Base class used as an abstract method's parameter?

我正在嘗試設置一些類,如:

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)繼承。

存在那些AnimalDefaultClass衍生因為每個Animal類都有不同的屬性,但根據定義,總會有一個類能夠為任何Animal獲取這些值。

我的問題是:

即使MammalDefaultClass繼承自AnimalDefaultClass,復制版本的CopyFrom(MammalDefaultClass)也不會被識別為抽象CopyFrom(AnimalDefaultClass)的有效覆蓋。

是否可以將基類指定為抽象成員的參數? 有一個簡單的*解決方法嗎? 或者整個事情是錯誤的嗎?

-edit:我的解決方案 -在玩了一些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),這是將抽象方法放在基類中的重點。

我想你可以嘗試抽象工廠模式。 基本上你想創建對象過程中處理一些建築的邏輯,並為每個不同亞型的產品 ,你可以做不同的。

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

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

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

    public Mammal(string speciesName) : base(speciesName)
    {
    }

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

public interface IAnimalFactory<T> where T : AnimalBase
{
    T CreateAnAnimal(string speciesName);
}

public class MammalFactory: IAnimalFactory<Mammal>
{
    public Mammal CreateAnAnimal(string speciesName)
    {
        var mammal = new Mammal(speciesName);
        var mammalDefault = new MammalDefaultClass(speciesName);
        mammal.WalksUpright = mammalDefault.WalksUpright;
        return mammal;
    }
}

當你想創建一個子類型對象時,你可以做到

var mammalFactory = new MammalFactory();
var bunny = mammalFactory.CreateAnAnimal("Bunny");

事實證明,即使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中的行為),那么解決方法是采用原始類型簽名並拋出錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM