[英]in c# oop how to explain why a base class can take a derived class instance
如果Y继承X,则Y是X 的一种,可以在X可以使用的任何地方使用。
无论X是否为抽象,这都将起作用。
Y类要么继承X类,要么X是Y继承的接口。
但是如果有人问我在工作面试中,我会告诉他们我不想在开发人员使用单个字符名称创建类型的任何地方工作。
为了扩展BrankoDimitrijević的答案,这可能是由于Liskov替代原理 。
在您的评论中,您说
基类和派生类可以具有各自不同的方法/属性/字段定义。 因此,从逻辑上讲,该语句不应该编译...但是可以编译...我不知道其背后的原理
的确,基类和派生类具有自己的成员定义,但它们并不完全不同。 具体来说, 基类的每个成员也是派生类的成员。 例如,您总是可以说
object o = anything;
Console.WriteLine(o.ToString());
Console.WriteLine(o.GetHashCode());
Console.WriteLine(o.GetType().Name);
您可以执行此操作,因为每个对象都具有ToString,GetHashCode和GetType方法 ,因为每个对象的运行时类型直接或间接地从对象继承。
您可以对object以外的基类执行相同的操作:
class X
{
public string Exclamation { get { return "Inherit this!"; } }
}
class Y : X
{
public string Question { get { return "What's up with that?"; } }
}
那是完全合法的说法
X x = new Y();
Console.WriteLine(x.Exclamation);
但是你当然不能说
X x = new Y();
Console.WriteLine(x.Question); //does not compile!
为了使用Question属性,您需要具有类型Y的引用。
回顾一下:由于基类的每个成员也是派生类的成员,因此可以将派生类的实例当作基类的实例一样使用。 派生的类实例具有基类的所有成员。
您提出了抽象类的主题。 当然,不能实例化抽象类。 您只能实例化从抽象类派生的类。 这并不影响替换原则,但是,不同之处为暗示一个变量,其类型是一个抽象类必须引用派生类型的一个实例,而一个变量,其类型是一个非抽象(未密封)类可以指派生类型的实例。
让我们假设
class Animal
{
}
class Tiger:Animal
{
}
Animal fooAnimal = new Tiger()
这是可能的,因为Tiger
是Animal
。
C#支持所谓的协方差和逆方差。 协方差是隐式地(无需任何额外代码)将派生类(在这种情况下为Y)转换为基类(在这种情况下为X)的能力。这是可能的,因为Y扩展了X,这意味着Y具有与X相同的所有成员。这允许将类型X的变量分配给派生类。
这对于扩展类和重载很重要。 如果类X包含一个名为Foo的方法,而派生类X创建一个名为Foo的方法,则即使将Y的方法强制转换为类型X,也将对其进行调用。这是一个示例:
public class X
{
public void Foo()
{
Console.WriteLine("Something");
}
}
public class Y : X // y derives from X
{
public override void Foo()
{
Console.WriteLine("Class Y");
}
}
public class Program
{
static void Main()
{
X item = new Y(); // covariance.
item.Foo(); // prints "Class Y"
}
}
我希望这不是随便的,我不知道您的技能水平。 来自MSDN的这篇文章对其进行了解释, 网址为http://msdn.microsoft.com/zh-cn/library/ee207183.aspx 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.