假设我有两个类如下:
class Fruit
{
public string color { get; set; }
}
class Orange : Fruit
{
public double diameter { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
然后在fruit变量中创建一个橙色对象
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 );
Run Code Online (Sandbox Code Playgroud)
为什么整个橙子,包括直径属性,可以挤进水果变量?为什么水果变量不受Fruit类定义的限制?
如果我将新的Orange放在Orange变量中,那么会有什么不同,如本例所示?
Orange fruit = new Orange() { color = "Orange", diameter = 10.0 };
Run Code Online (Sandbox Code Playgroud)
我能找到的唯一区别是,如果我对变量进行类型测试,并且在使用对象之前我不需要强制转换.但它必须有更多,对吧?
Fruit是一种概括,Orange而是一种专业化.专用对象可以即兴创建现有的继承属性,也可以添加特定于其的属性.
为什么整个橙子,包括直径属性,可以挤进水果变量?
fruit只是一个引用变量,但它引用Orange可能存在于堆中的新对象.该Orange对象的定义足以容纳该diameter属性.超类引用类型可以引用子类对象.这样就可以实现多态性.如果你做这样的事情fruit.color,那么在运行时你可以访问color任何扩展的子类的属性Fruit和fruit当前引用的对象.
为什么水果变量不受Fruit类定义的限制?
当你这样做:
Fruit fruit = new Orange() { color = "Orange", diameter = 10.0 };
Run Code Online (Sandbox Code Playgroud)
您正在给自己一个在代码中实现多态性的机会.如果声明一个方法传递Fruit类型作为参数,那么您可以使用Fruit类型引用变量来访问属性或在其上调用方法,而不实际将您的方法限制为特定Fruit类型.在未来,如果你想具体的水果从改变Orange到Apple,在Apple延长Fruit,那么你就可以重新使用该方法,并确保至少在定义的方法或属性Fruit会为特定果型工作.
如果我将新的Orange放在Orange变量中,会有什么不同
正如我前面提到的,如果你使用特定的类型引用,那么你就无法利用多态性.