c#中的方法重写
本文关键字:重写 方法 | 更新日期: 2023-09-27 18:02:12
考虑到以下内容:
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
类的实例
你所做的不是覆盖,而是遮蔽。new
关键字允许您在BC
和DC
类中都有Display
方法,但是这些方法根本不相关,它们只是具有相同的名称。
要覆盖该方法,您需要为BC
类中的方法使用virtual
关键字,并在DC
类中使用overrides
方法。
当你遮蔽一个方法时,是引用的类型决定了使用哪个方法:
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;
你不是一个人。请看这个问题的答案:我想知道新的关键字在内部做什么。
关于virtual/new/override的混淆
和接下来的问题:
更多关于Virtual/new…+接口!
将Display
设置为BC中的虚函数,并在DC中重写,然后它将按您期望的方式工作