【发布时间】:2014-05-13 15:03:08
【问题描述】:
我读到new 修饰符隐藏了基类方法。
using System;
class A
{
public void Y()
{
Console.WriteLine("A.Y");
}
}
class B : A
{
public new void Y()
{
// This method HIDES A.Y.
// It is only called through the B type reference.
Console.WriteLine("B.Y");
}
}
class Program
{
static void Main()
{
A ref1 = new A(); // Different new
A ref2 = new B(); // Polymorpishm
B ref3 = new B();
ref1.Y();
ref2.Y(); //Produces A.Y line #xx
ref3.Y();
}
}
为什么ref2.Y(); 产生A.Y 作为输出?
这是简单的多态,基类对象指向派生类,所以应该调用派生类函数。我实际上是 Java 兼 C# 编码器;这些概念让我大吃一惊。
当我们说new隐藏基类函数时,这意味着base类函数不能被调用,据我所知,这就是隐藏的意思.
【问题讨论】:
-
避免使用
new修饰符。它引入了一个具有相同名称的不相关成员(在像这里这样的方法的情况下是签名),但原始(继承)成员也在那里。这会导致混乱。在您的示例中,B实例具有 两个 实例方法,称为Y()。使用ref3.Y(),您会看到B中声明的那个优先于继承的那个。这就是所有“隐藏”的意思。如果您真的想要一个不相关的方法,请使用未使用的名称并避免使用new。如果您想要多态性,请按照答案的建议使用override。 -
@JeppeStigNielsen ref3.Y() 是纯 B 类调用,我没有提到 Y() 是虚拟的,所以它根本没有继承,如果我说猫隐藏了孩子,那就意味着猫在孩子面前,类似地,如果派生类函数隐藏了基类函数,那么派生类函数应该被调用,因为基类一被隐藏
-
肯定会继承非虚方法。
-
@JeppeStigNielsen 我明白了,可能是太多的 Java 编码毁了我的概念。还是谢谢你
-
这个“隐藏”术语的唯一一点是:如果一个类型有两个外观相同的成员,一个是从某个基类继承的,另一个是在这个类中声明的,通过从更专业的类中选择方法来解决歧义。这就是它的全部。
new修饰符实际上并没有改变任何东西(除了抑制编译时警告)。没有new(如果您容忍编译器警告),您将获得完全相同的行为。new只是为了告诉编译器“我知道我在做一些愚蠢的事情,放松一下”。
标签: c# .net oop polymorphism new-operator