我对术语有问题。根据 MSDN:"重写修饰符扩展了基类方法,新修饰符隐藏了它。 但是,在以下示例中:
using System;
namespace ConsoleApplication2
{
class BaseClass
{
public virtual void Method1()
{
Console.WriteLine("Base - Method1");
}
}
class DerivedClass : BaseClass
{
public void Method1() // DerivedClass.Method1() hides inherited memeber BaseClass.Method1(). Use the new keyword if hiding was intended.
{
Console.WriteLine("Derived - Method1");
}
}
class Program
{
static void Main(string[] args)
{
BaseClass bd = new DerivedClass();
bd.Method1();
Console.ReadLine();
}
}
}
如果你在DerivedClass中使用new来声明Method1(),bd,你会看到这一点。方法1()将输出:"基 - 方法1",如基类中的指示。
。然而,如果您在 DerivedClass 中声明 Method1() 时使用覆盖,bd。Method1() 将输出:"派生 - 方法1",如派生类中的指示。
为什么每个来源(包括官方文档)都说new隐藏了基类方法,而在这个例子中,基类方法是使用new时调用
的方法?我理解不同的行为(与覆盖相比是新的),但不了解术语。
该方法对基类隐藏该方法是什么意思?
class BaseClass
{
public virtual void Method1()
{
Console.WriteLine("Base - Method1");
}
}
class DerivedClass : BaseClass
{
public void Method1() // DerivedClass.Method1() hides inherited memeber BaseClass.Method1(). Use the new keyword if hiding was intended.
{
Console.WriteLine("Derived - Method1");
}
}
想象一下,如果你写了以下内容:
var dc = new DerivedClass();
dc.Method1();
编译并运行此代码,并调用派生方法。但是现在,删除Method1
BaseClass
.代码的编译和运行仍然完全相同。
Method1
inDerivedClass
BaseClass
中隐藏了Method1
方法,不让任何直接使用DerivedClass
(或任何其他派生实例)的人看到
new
有几种用途。您引用的文档中提到的是声明修饰符。
可以通过三种方式声明派生类中的Method1()
:
public void Method1() // 1
public new void Method1() // 2
public virtual void Method1() // 3
版本 1 和 2 都在基类中隐藏了同名的虚拟方法,因此当对基类变量调用时,将调用BaseClass.Method1()
。但是版本 2(带有new
)明确隐藏了基类方法,即您告诉编译器这是故意的。版本 1隐式隐藏虚拟方法,并将导致警告,因为编译器假定这可能是意外的,而不是故意的。
隐藏并不意味着你认为它的作用。这意味着在DerivedClass
及其任何后代中,Method1()
不是虚拟的,并且您不能再在DerivedClass
上调用虚拟方法。他们说虚拟方法对DerivedClass
是隐藏的.这意味着它打破了(继承)多态性。
版本 3覆盖同名的方法,如果某个方法是虚拟的,则无论变量如何声明,都将调用实际方法。所以如果变量被声明为BaseClass
,但实际上类是一个DerivedClass
,那么导数的方法将被调用。
更多信息:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/new-modifier
请注意,new
的使用与您理解的不一样:
BaseClass bd = new DerivedClass();
这是一个不同的new
,而不是声明修饰符。