好吧,由于我是从手机输入的,所以我无法输入或复制粘贴整个代码,因此我链接到SO帖子-> What is the error in this code? Interview

如果你这样做
    X a = new Y();
它编译。面试官问这怎么可能?我知道,如果将X定义为抽象类,这将是可能的,但事实并非如此。

最佳答案

为了扩展BrankoDimitrijević的答案,由于Liskov substitution principle的缘故,这是可能的。

在您的评论中,您说


  基类和派生类可以具有各自不同的方法/属性/字段定义。因此,从逻辑上讲,该语句不应该编译...但是可以编译...我不知道其背后的原理


的确,基类和派生类具有自己的成员定义,但它们并不完全不同。具体来说,基类的每个成员也是派生类的成员。例如,您总是可以说

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的引用。

回顾一下:由于基类的每个成员也是派生类的成员,因此您可以使用派生类的实例,就像它是基类的实例一样。派生的类实例具有基类的所有成员。

您提出了抽象类的主题。当然,不能实例化抽象类。您只能实例化从抽象类派生的类。但是,这并不影响替代原理,只是暗示类型为抽象类的变量必须引用派生类型的实例,而类型为非抽象(未密封)类的变量可以引用。派生类型的实例。

关于c# - 在C#oop中如何解释为什么基类可以采用派生类实例,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9526872/

10-12 00:30
查看更多