![](/img/trans.png)
[英]abstract class with more then one parameterized constructor and derived class with parameterized constructor
[英]Using abstract class as parameter in base class constructor to have more specific types in derived classes
來自數據科學,我正在嘗試使用C#學習oop進行軟件開發。
我正在嘗試建立一個基類(例如Aliments),將從中派生其他一些甚至更具體的自定義列表類(例如Fruits和Vegs)。 在側面,我有一些分別來自Aliment的Fruit和Veg類。 最后,我希望Fruits / Vegs實例具有Veg / Fruit專有性列表(以及一些針對Fruits和Vegs類的專有性和方法)。 但我希望此列表適當性在Aliments基類中實現,並提供一些管理它的方法(例如RemoveRipe(),SortBySize()...)
我試圖在Aliments類中放置一個List適當性,然后使用List <Fruit>或List <Veg>使派生類(Fuits / Vegs)調用基本構造函數。
我嘗試過這樣的事情:
public abstract class Aliment
{
public int Ripeness;
}
public class Fruit : Aliment
{
// be a fruit
}
public abstract class Aliments
{
public Aliments(List<Aliment> alimentList)
{
AlimentList = alimentList;
}
public List<Aliment> AlimentList { get; private set; }
public void RemoveRipe()
{
//...
}
}
public class Fruits : Aliments
{
public Fruits(List<Fruit> fruitList)
: base(fruitList)
{
}
}
主要問題是水果清單無法轉換為食品清單。 此外,操作的重點是每個“水果”實例都有一個“實際水果”列表(以便我可以訪問“水果”的特定方法)。 有什么辦法可以做到嗎? 我的方法好嗎? 提前致謝
PS對不起,如果它是重復的,我真的沒有如何提出問題以便進行搜索
當我們說不能將List<Fruit>
轉換為List<Aliment>
,很大程度上取決於我們所說的“轉換”。
如果您有一個List<Fruit>
並且想要一個List<Ailment>
,則可以通過創建一個新列表來實現。 例如,如果fruitList
是List<Fruit>
:
var alimentList = new List<Aliment>(fruitList.Cast<Aliment>())
因為每種Fruit
都是一種Aliment
,所以您可以將每種Fruit
澆鑄為一種Aliment
並使用它們填充新的List<Aliment>
。
如果這樣做,那么Fruits
構造函數將編譯:
public class Fruits : Aliments
{
public Fruits(List<Fruit> fruitList)
: base(new List<Aliment>(fruitList.Cast<Aliment>()))
{ }
}
我們不能做的是將 List<Fruit>
為List<Aliment>
。
為什么? 因為如果可以的話,我們可以這樣做:
var alimentList = (List<Aliment>)fruitList;
alimentList.Add(new Vegetable());
那不會創建一個新列表-它只會將列表強制轉換為其他類型。 但是,如果我們可以將List<Fruit>
為List<Aliment>
則可以向列表添加任何Aliment
,包括Vegetable
。 然后我們的List<Fruit>
中將有Vegetable
。
對於我們來說,這並不總是顯而易見的,但是編譯器會立即發現並阻止它。
因此,如果使用上面顯示的代碼來修復構造函數中的錯誤,您仍然會遇到完全相同的問題。 Fruits
將仍然具有從Aliments
繼承的List<Aliment>
屬性,因此您仍然可以這樣做:
var fruits = new Fruits(someListOfFruit);
fruits.AlimentList.Add(new Vegetable());
那不會給您一個編譯器錯誤,但顯然仍然不是您想要的行為。
像這樣的通用類可能會幫助您:
public abstract class Aliments<T> where T : Aliment
{
public Aliments(List<T> alimentList)
{
AlimentList = alimentList;
}
public List<T> AlimentList { get; private set; }
}
它允許您執行此操作。 您可以定義一個繼承自Aliments
但指定Aliment
的實際類型的類。
public class Fruits : Aliments<Fruit>
{
public Fruits(List<Fruit> alimentList) : base(alimentList)
{
}
}
通過為通用參數T
指定Fruit
,您的AlimentList
屬性現在定義為List<Fruit>
。 編譯器將只允許您向其中添加Fruit
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.