0

假设我有两个类如下:

class Fruit
{
    public string color { get; set; }
}
class Orange : Fruit
{
    public double diameter { get; set; }
}

然后在水果变量中创建一个橙色对象

Fruit fruit = new Orange() { color = "Orange", diameter = 10.0 };

// This line prints 10 even though the Fruit class doesn't contain a
// diameter property
Console.WriteLine( ( (Orange) fruit ).diameter );

为什么整个橙子,包括直径属性,都可以挤进水果变量?为什么 Fruit 变量不受 Fruit 类定义的限制?

如果我将新的 Orange 放在 Orange 变量中,会有什么区别,就像在这个例子中一样?

Orange fruit = new Orange() { color = "Orange", diameter = 10.0 };

我能找到的唯一区别是我是否对变量进行类型测试,并且在使用对象之前我不需要强制转换。但肯定不止于此,对吧?

4

3 回答 3

5

Fruit是泛化,Orange而是特化。专门的对象可以在现有的继承属性上即兴发挥,或者可以添加特定于它的属性。

为什么整个橙子,包括直径属性,都可以挤进水果变量?

fruit只是一个引用变量,但它引用Orange可能位于堆中的新对象。该Orange对象被定义为足够大以容纳该diameter属性。超类引用类型可以引用子类对象。这样你就可以实现多态。如果你做这样的事情fruit.color,那么在运行时你可以访问color任何扩展的子类的属性以及当前引用Fruit的对象。fruit

为什么 Fruit 变量不受 Fruit 类定义的限制?

当你这样做时:

Fruit fruit = new Orange() { color = "Orange", diameter = 10.0 };

您正在给自己一个在代码中实现多态性的机会。如果您声明一个将Fruit类型作为参数传递的方法,那么您可以使用Fruit类型引用变量来访问属性或调用其上的方法,而无需实际将您的方法限制为特定Fruit类型。将来,如果您想将特定水果从 to 更改为Orangewhere Appleextends AppleFruit那么您可以重复使用该方法,并确保至少其中定义的方法或属性Fruit适用于该特定水果类型。

如果我将新的 Orange 放在 Orange 变量中会有什么区别

正如我前面提到的,如果你使用特定的类型引用,那么你就不能利用多态性。

于 2013-06-19T07:34:22.513 回答
1

这称为运行时多态性。扩展了水果并添加了新的Orange属性,例如直径。当您创建一个对象Orange并将其放入 aFruit时,它会保留其属性,只有该水果无法解决这些问题。然后你需要再做一次OrangeFruit以获得直径。

来自维基百科

在计算机科学中,多态性是一种编程语言特性,允许使用统一接口处理不同数据类型的值。参数多态性的概念适用于数据类型和函数。可以计算或应用于不同类型值的函数称为多态函数。可以看起来是通用类型的数据类型(例如,具有任意类型元素的列表)被指定为多态数据类型,就像进行这种专门化的通用类型一样。

于 2013-06-19T07:38:48.043 回答
0

这基本上是因为您正在创建 Orange,而 Fruit 是 Orange 的概括。它只是实际 Orange 对象的包装。重要的是您正在创建橙色并将其指定为水果,但水果是橙色。如果你这样做

Fruit _fruit = new Fruit()

那将是不同的。您正在创建 Orange,而 Orange 继承自 Fruit,这就是您可以这样编写的原因。

于 2013-06-19T07:36:00.027 回答