首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在基类构造函数中使用抽象类作为参数,以便在派生类中具有更特定的类型。

在基类构造函数中使用抽象类作为参数,以便在派生类中具有更特定的类型。
EN

Stack Overflow用户
提问于 2019-05-04 17:16:05
回答 1查看 58关注 0票数 1

来自数据科学,我正在尝试学习使用c#进行软件开发的oop。

我正在尝试建立一个基类(例如,赡养费),其他几个更具体的定制列表类将从中派生出来(例如水果和Vegs)。在这方面,我有个别的水果和维格类,这些类都是从赋值中派生出来的。最后,我希望水果/织女星的例子有一个Veg/水果礼仪的列表(以及一些特定于水果和Vegs类的礼仪和方法)。但我希望在赡养费基类中实现这个列表,并提供一些管理它的方法(例如RemoveRipe()、SortBySize().)

我试图在赡养费类中放置一个适当的列表,然后使派生类(Fuits/Vegs)用一个列表或列表调用基构造函数。

我试过这样的方法:

代码语言:javascript
运行
复制
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)
    {

    }
}

主要问题是水果清单不能转化为赡养费清单。此外,操作的重点是每个水果实例都有一个实际果树的列表(这样我就可以访问果树的具体方法)。有什么办法我能做到吗?我走得好吗?提前感谢

对不起,如果是重复的话,我并没有真正地提出这个问题,以便寻找它。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-04 17:51:48

当我们说不能将List<Fruit>转换为List<Aliment>时,很大程度上取决于我们所说的“转换”是什么意思。

如果您有一个List<Fruit>,并且您想要一个List<Ailment>,您可以通过创建一个新的列表来实现这一点。例如,如果fruitListList<Fruit>

代码语言:javascript
运行
复制
var alimentList = new List<Aliment>(fruitList.Cast<Aliment>())

因为每个Fruit都是Aliment,所以可以将它们转换为Aliment,并使用它们填充新的List<Aliment>

如果这样做,您的Fruits构造函数将编译:

代码语言:javascript
运行
复制
public class Fruits : Aliments
{
    public Fruits(List<Fruit> fruitList)
        : base(new List<Aliment>(fruitList.Cast<Aliment>()))
    { }
}

我们不能做的是将List<Fruit>转换为List<Aliment>

为什么?因为如果我们能做到的话:

代码语言:javascript
运行
复制
var alimentList = (List<Aliment>)fruitList;
alimentList.Add(new Vegetable());

这将不会创建一个新的列表-它将简单地将列表作为一个不同的类型。但是,如果我们可以将List<Fruit>转换为一个List<Aliment>,那么我们就可以将任何Aliment添加到列表中,包括一个Vegetable。那么我们的List<Fruit>中就会有一个List<Fruit>

这对我们来说并不总是显而易见的,但是编译器马上就会发现并阻止它。

由于这个问题,如果您使用我前面展示的代码来修复构造函数中的错误,您仍然会遇到完全相同的问题。Fruits仍然有一个从Aliments继承的List<Aliment>属性,所以您仍然可以这样做:

代码语言:javascript
运行
复制
var fruits = new Fruits(someListOfFruit);
fruits.AlimentList.Add(new Vegetable());

这不会给你一个编译器错误,但这显然不是你想要的行为。

可以帮助您的是这样一个泛型类:

代码语言:javascript
运行
复制
public abstract class Aliments<T> where T : Aliment
{
    public Aliments(List<T> alimentList)
    {
        AlimentList = alimentList;
    }
    public List<T> AlimentList { get; private set; }
}

它允许你这样做。您可以定义一个从Aliments继承但指定实际Aliment类型的类。

代码语言:javascript
运行
复制
public class Fruits : Aliments<Fruit>
{
    public Fruits(List<Fruit> alimentList) : base(alimentList)
    {
    }
}

通过为泛型参数Fruit指定T,您的AlimentList属性现在被定义为List<Fruit>。编译器只允许您将Fruit添加到它。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55984994

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档