C# base inheritance

本文关键字:inheritance base | 更新日期: 2023-09-27 18:36:59

这个问题一直困扰着我,我现在写了 4 个包装器。我确定我做错了,需要弄清楚我的理解在哪里分支。

假设我使用 Rectangle 类来表示金属条。(这比动物效果更好)

所以说基类被称为"Bar"。

private class Bar
{
   internal Rectangle Area;
}

所以。现在我们做一个矩形,比如说 300 个单位乘以 10 个单位。

private Bar CreateBar()
{
    Bar1 = new Bar1();
    Bar1.Area = new Rectangle(new Point(0,0), new Size(300,10));
    return Bar1;
}

太棒了,所以我们有一个基础栏。

现在假设我们想让这个棒材有一种材料——比如钢。所以。

private class SteelBar : Bar
{
    string Material;
}

所以如果我这样做了

。。。
private SteelBar CreateSteelBar()
{
    SteelBar SteelB = new SteelB();
    Bar B = CreateBar();
    SteelB = B;
    SteelB.Material = "Steel";
    return SteelB;
}

从我从中得到的,如果我称之为CreateSteelBar,它会创建一个称为CreateBar的钢筋。所以我最终得到了一个带有 300 x 10 矩形的钢筋,以及一个空或空的材料字符串。然后我将材料设置为钢。

当我在我的程序中尝试类似的东西时,它一直告诉我不能从较低的下级隐式创建一个更高的上级类。考虑到我看到的所有动物例子的遗传,我会认为这就是遗传存在的原因,但我希望有人能澄清我。

另外,我确信我可以打电话给SteelBar = CreateBar();但我在这里做了很长的路。

C# base inheritance

而不是使用方法 ( CreateBar ),您将使用构造函数

public Bar()
{
    this.Area = new Rectangle(new Point(0,0), new Size(300,10));
}

然后,在 SteelBar 中,您将调用基类构造函数:

public SteelBar()
{
    this.Material = "Steel";
}

基类构造函数将首先出现,因此您的区域已经设置好。 不过,您可以明确说明这一点,并在代码中显示它:

public SteelBar()
    : base()
{
    this.Material = "Steel";
}

但是,这通常仅在您希望具有接受参数的特定构造函数时才使用。

有关详细信息,请参阅 C# 编程指南中的构造函数。

这是你的问题:

Bar B = CreateBar();
SteelB = B;

B任何类型的酒吧。您正在尝试将其分配给SteelBar。这是错误的,它可以是任何类型的酒吧(铜,木材,Tiki,...您可以这样做:

SteelBar sb = new SteelBar();
Bar b = sb;

因为SteelBar是某种酒吧,但反之则不然。

另外,我确定我可以调用 SteelBar = CreateBar()

你确定某些事情是错误的。试试吧; CreateBar 返回任何类型的柱线的实例,而不是SteelBar

正如 pycruft 所提到的,您不能将基类型的对象分配给子类型变量。我不明白你为什么要添加一个SteelBar,因为你也有Material属性。这对我来说似乎是多余的。

为了实现您要做的事情,您必须创建一个从头开始构建SteelBar的新工厂方法。无论如何,它可能会将其作为Bar返回。这将是工厂模式的实现。

但是,有关您要实现的目标的更多信息可能会有所帮助。

它一直告诉我不能隐式地从 下级

我为此使用的最好的例子是 Fruitapple .继承是一种"是"关系。 appleFruitFruit不是apple,因为它可以是orangebanana...

回到您的示例,SteelBar是一个BarBar不是SteelBar因为它可以是 WoodenBar这就解释了为什么你不能将超类转换为子类

你不能这样做:

SteelBar = B;

您已经创建了一个 Bar 类型的新对象,并尝试将其分配给 SteelBar 类型的引用。

当然,

使用诸如接口之类的抽象会更容易实现...例如,不可获取的和IPhysical的,而不是基类...

我将仅在 GUI 表示中使用 BaseClass 以便于显示它们,并且我会强制基类实现所需的接口。

您也可以选择使用密封的显示对象,并采用IMeasureable或IPhysical...

我很

确定你的问题是你试图向上投射:

Bar B = CreateBar();
SteelBar = B;

这是不对的,因为即使 SteelBar 必须是 Bar 型(因为它继承自),也不能向后完成相同的操作。

反之则合法:

SteelBar B = CreateBar();
Bar = (Bar)B;

很简单,您正在尝试在Bar中存储SteelBar的引用,而它可能是另一种柱线类型,例如WoodenBar

考虑这个例子:

public class Super {
}
public class Sub : Super {
}

如果创建对象 Super,则无法将其指定为 Sub,因为它不是"Sub"。OO编程允许您根据派生较少的类"处理"对象,但这个简单的事实仍然存在:

您创建了一个超级而不是潜艇。

从超级创建 Sub 的唯一方法是创建一个新的 Sub 并复制属性值。像AutoMapper这样的工具可以很好地快速完成此操作,否则您最终会得到一堆平凡的脆弱代码。