我有一個這樣的類結構:
BaseAnimal.cs:
public abstract class BaseAnimal
{
public string? Species { get; set; }
public double Price { get; set; }
}
然后我有這兩個類:
public abstract class Carnivore : BaseAnimal
{
public double MeatFood { get; set; }
}
public abstract class Herbivore : BaseAnimal
{
public double GreenFood { get; set; }
}
然后我有子類:
public class Ape : Herbivore
{
public Ape()
{
Species = "Ape";
GreenFood = 10.0;
Price = 10000.0;
}
}
然后我有一個工廠,它已經在使用這條線來獲取動物的所有屬性:
public BaseAnimal[] Animals = prototypes.Values.ToArray();
在我的主要課程中,我想閱讀動物的屬性:
private void cboAnimals_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Debug.WriteLine(animalFactory.Animals[0].);
}
這段代碼的問題是,我無法訪問 Herbivore.cs 和 Carnivore.cs 中指定的屬性
uj5u.com熱心網友回復:
你應該做的是使用組合。
public interface IFood {
public double Food { get; set; }
}
public class Herbivore {
public double Food { get; set; }
}
public class Carnivore {
public double Food { get; set; }
}
public interface IAnimal {
string? Species { get; set; }
double Price { get; set; }
}
public class Animal {
string? Species { get; set; }
double Price { get; set; }
}
public class Ape {
private IAnimal _animal;
private IFood _food;
public Ape(IAnimal animal, IFood food) {
_animal = animal;
_food = food;
}
}
Now you can compose any class of type animal you want, you can reuse the implementation of IAnimal and IFood on other types, make new ones? Like Omnivore?
您可以實作不同的物種,和/或“價格”并將其加載到您想要的任何新類中,例如“狗”或“貓”,并使用您的介面組合該物件。因此不需要重寫你的測驗,你不需要有多個實作說......“說話”對所有做“吠叫”的狗你可以有一個會“吠叫”的類,然后將它組合成所有狗喜歡動物。
uj5u.com熱心網友回復:
最簡單的可能是檢查型別:
var foodAmount = animalFactory.Animals[0] switch {
Carnivore c => c.MeatFood ,
Herbivore h => h.GreenFood ,
_ => throw new InvalidOperationException()
};
但這是介紹性編程中教授的典型繼承示例。作為一般規則,如果您需要檢查型別,您可能沒有充分考慮您的型別系統。繼承的想法是所有特定于實作的東西都應該委托給實作,所以物件的用戶不需要知道具體的型別。
因為這個例子太人為,所以我很難提供具體的建議,但我建議閱讀 Eric Lippert 關于奇才和勇士的系列,以很好地介紹繼承,以及人們經常做錯的事情。
uj5u.com熱心網友回復:
問題是動物陣列的型別是 BaseAnimal。您需要將其拆箱(即將其轉換為它的子型別),您還需要一些邏輯來檢查型別,所以類似于
if (obj is Herbivore)
{
var herb = (Herbivore)obj;
herb.Greenfood= 123m;
}
它看起來很亂,但在某些時候你需要得到具體的型別。
uj5u.com熱心網友回復:
Animals是一個陣列BaseAnimal。此類沒有 aMeatFood或GreenFood屬性。這就是您無法訪問這些屬性的原因。如果您可以訪問它們,則可以使用以下代碼:
BaseAnimal animal = new Ape();
Console.WriteLine(animal.MeatFood);
但Ape沒有MeatFood財產。如果你想訪問這些屬性,你必須知道你的Animals[0]是 aCarnivore還是 a Herbivore:
private void cboAnimals_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if(animalFactory.Animals[0] is Carnivore carnivore)
{
Debug.WriteLine(carnivore.MeatFood);
}
else if (animalFactory.Animals[0] is Herbivore herbivore)
{
Debug.WriteLine(herbivore.GreenFood);
}
}
但也許你現在意識到你不會得到好的代碼。這表明你的班級結構不是最好的。事實上,為什么你有兩個屬性MeatFood和GreenFood?它們之間有什么區別?兩者都是雙重型別。因此,也許您應該Food在您的班級中有一個屬性,BaseAnimal并通過列舉來區分食物的型別:
public enum FoodType
{
Meat,
Green
}
public abstract class BaseAnimal
{
public string? Species { get; set; }
public double Price { get; set; }
public double Food { get; set;}
public abstract FoodType FoodType {get;}
}
public abstract class Carnivore : BaseAnimal
{
public override FoodType FoodType{ get { return FoodType.Meat; } }
}
public abstract class Herbivore : BaseAnimal
{
public override FoodType FoodType{ get { return FoodType.Green; } }
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/444776.html
下一篇:不要列印id以特殊字符開頭的員工
