C# C中的方法重写#

C# C中的方法重写#,c#,oop,inheritance,C#,Oop,Inheritance,鉴于以下情况: 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() {

鉴于以下情况:

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
关键字只是告诉编译器你想将标识符重新用于基类以外的东西。重写方法时,方法签名必须相同

例如,您可以对一个公共方法进行阴影处理,该方法使用与
int
类型的私有属性完全不同的
string

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;

使
在BC中显示
一个虚拟函数并在DC中重写,然后它将按照您期望的方式工作

我想知道新关键字在内部做什么

你并不孤单。请参见此问题的答案:

接下来的问题是:


有关如何实现虚拟、新建、重写和接口实现的详细但仍然较高层次的解释。

您说过——重写方法时,方法是相关的,决定使用哪种方法的是对象的实际类型,而不是引用的类型。什么是参考类型?这里的意思是。你说过——重写和隐藏之间的另一个区别是,当你对一个方法进行隐藏时,这个方法根本不必是相似的,new关键字只是告诉编译器你想在基类以外的地方重用标识符。重写方法时,方法签名必须相同。你能不能跟示例代码讨论一下,shadow方法根本不必是相似的,覆盖一个方法时,方法签名必须是相同的。plzz附带示例代码,以便更好地理解。感谢当您创建类型为
BC
的变量时,它包含类型为
BC
的引用。即使您创建一个
DC
的值并分配给变量,引用的类型仍然是
BC
。我在上面添加了一个示例,它表明您可以使用完全不同的内容进行阴影处理。请详细讨论new关键字的工作方式以及new关键字给编译器的指令。