我的术语有问题。根据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中声明Method1()时使用 new ,bd.Method1()将按照基类中的指示输出:“Base - Method1”。
...然而,如果在DerivedClass中声明Method1()时使用覆盖,bd.Method1()将按照派生类中的指示输出:“Derived - Method1”。
为什么每个来源(包括官方文档)都说新 隐藏 基础类方法,在此示例中明确表示基础class方法是使用new?
时调用的方法我理解不同的行为(新的与覆盖相比)但不是术语。
答案 0 :(得分:1)
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://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/new-modifier
请注意,new
的使用与您理解的不同:
BaseClass bd = new DerivedClass();
这是一个不同的new
,而不是声明修饰符。
答案 1 :(得分:1)
方法从基类隐藏方法是什么意思?
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
DerivedClass
隐藏 Method1
方法中的BaseClass
方法来自任何人使用 DerivedClass
直接(或任何进一步派生的实例)