![](/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.