鉴于以下内容:
class BC
{
public void Display()
{
System.Console.WriteLine("BC::Display");
}
}
class DC : BC
{
new public void Display()
{
System.Console.WriteLine("DC::Display");
}
}
class Demo
{
public static void Main()
{
BC b;
b = new BC();
b.Display();
b = new DC();
b.Display();
}
}
我理解以下代码调用基类Display()
方法:
BC b;
b = new BC();
b.Display();
以下几行调用派生类Display()
,它通过使用new
关键字来隐藏基类实现:
b = new DC();
b.Display();
我想知道new
关键字在内部的作用。
此代码的来源包括以下说明:
由于b包含对DC类型对象的引用,因此可以期望执行DC类的函数
Display()
。但这不会发生。相反,执行的是BC类的Display()
。那是因为函数是根据引用的类型而不是引用变量b引用的内容来调用的。由于b是BC类型的引用,因此无论b指的是谁,都将调用BC类的函数Display()
。
我对这一点非常困惑:“因为函数是根据引用的类型调用的,而不是参考变量b引用的内容”
根据引用的类型调用“函数”是什么意思
b = new DC();
b.Display();
这里b
的类型是什么?它被声明为类BC
的实例名称
但后来b
成为了班级DC
的实例。
答案 0 :(得分:8)
你所做的不是压倒一切,而是遮蔽。 new
关键字允许您在Display
和BC
类中使用DC
方法,但这些方法根本没有关系,它们只是具有相同的名称。< / p>
要覆盖该方法,您需要对virtual
类中的方法使用BC
关键字,并在overrides
类中使用DC
方法。
当您为方法着色时,它是决定使用哪种方法的引用类型:
BC b1;
b1 = new BC();
b1.Display(); // Calls the method in BC
BC b2;
b2 = new DC();
b2.Display(); // Calls the method in BC
DC d1;
d1 = new DC();
d1.Display(); // Calls the method in DC
覆盖方法如下所示:
class BC {
public virtual void Display() {
System.Console.WriteLine("BC::Display");
}
}
class DC : BC {
override public void Display() {
System.Console.WriteLine("DC::Display");
}
}
覆盖方法时,方法是相关的,它是决定使用哪种方法的对象的实际类型,而不是引用的类型:
BC b1;
b1 = new BC();
b1.Display(); // Calls the method in BC
BC b2;
b2 = new DC();
b2.Display(); // Calls the method in DC
DC d1;
d1 = new DC();
d1.Display(); // Calls the method in DC
覆盖和阴影之间的另一个区别是,当您隐藏方法时,根本不必相似,new
关键字只是告诉编译器您要将标识符重用于除了在基类中。覆盖方法时,方法签名必须相同。
例如,您可以隐藏一个公共方法,该公共方法将string
与完全不同的东西(如int
类型的私有属性一样:
public class X {
public void XX(string z) { }
}
public class Y : X {
private new int XX { get; set; }
}
X x = new Y();
x.XX();
Y y = new Y();
y.XX = 42;
答案 1 :(得分:4)
我想知道新关键字在内部的作用。
你并不孤单。看看这个问题的答案:
Confusion about virtual/new/override
以及这个后续问题:
More about Virtual / new...plus interfaces!
有关如何实现虚拟,新建,覆盖和接口实现的详细但仍然高级的解释。
答案 2 :(得分:0)
在BC中使Display
成为虚拟函数并在DC中覆盖,然后它将以您期望的方式工作。