C# “什么是”呢;公开新的虚拟无效方法();什么意思?
什么时候用新的虚拟关键词来装饰的方法?什么是感情?比如定义一个接口,并添加一个类来继承接口。而采用新的虚拟仪器来实现接口方法C# “什么是”呢;公开新的虚拟无效方法();什么意思?,c#,C#,什么时候用新的虚拟关键词来装饰的方法?什么是感情?比如定义一个接口,并添加一个类来继承接口。而采用新的虚拟仪器来实现接口方法 interface IPrinter { void Print(); } public class PrinterOne : IPrinter { public void Print() { Console.WriteLine("PrinterOne."); } } public class PrinterTwo
interface IPrinter
{
void Print();
}
public class PrinterOne : IPrinter
{
public void Print()
{
Console.WriteLine("PrinterOne.");
}
}
public class PrinterTwo : PrinterOne
{
public new virtual void Print()
{
Console.WriteLine("PrinterTwo.");
}
}
public class PrinterThree : PrinterTwo
{
public override void Print()
{
Console.WriteLine("PrinterThree.");
}
}
public class PrinterFour : PrinterThree
{
public override void Print()
{
Console.WriteLine("PrinterFour.");
}
}
static void Main(string[] args)
{
IPrinter iprinter = new PrinterFour();
iprinter.Print();//the output is PrinterOne? why???
Console.ReadLine();
}
像这样使用的
new
关键字是成员隐藏
请注意,我从未见过它与virtual
关键字一起使用。它只允许从PrinterTwo
派生的类型覆盖Print
方法实现
以这种方式使用的
new
关键字允许类型隐藏基类型的成员,但仅当您使用类型本身的变量时
例如,如果您要执行以下操作:
PrinterOne one = new PrinterTwo();
one.Print();
它不会调用PrinterTwo
中的方法,因为它不是继承链的一部分
至于你什么时候会这么做。。。当你真的,真的因为我想不出的一些奇怪的原因(可能是反射?)而需要时,你不能在printrone
中编辑代码
就我个人而言,我永远不会这么做
至于为什么输出是打印机1。。。调用IPrinter.Print
将针对其定义的类型调用(PrinterOne
,在本例中),这将使您回到我上面的示例中,关于new
关键字被忽略,除非您与具有该关键字的类型对话
基本上,使用IPrinter
与上面的小示例中使用PrinterOne
类似
要解决此问题,请使
PrinterOne
方法virtual
,并完全取消PrinterTwo
new
和virtual
是两个(大部分)不相关的关键字
new
意味着它会隐藏基本方法。virtual
允许子类重写它
通过接口调用方法会导致调用基方法,因为基方法不是虚拟的,派生类不会显式地重新实现接口(这会导致方法重新映射)这称为方法隐藏。当需要为无法重写的方法提供自己的实现时,可以使用此选项。由于
printrone.Print
不是虚拟方法,因此无法重写它。相反,new
关键字用于创建相同的方法签名,该签名隐藏了原始方法。将使用新方法代替。将virtual
关键字添加到此中,可以通过派生类覆盖新方法
只有通过定义容器(例如,printwoo
)调用隐藏原始方法的新方法时,才会调用该方法。通过接口调用它将调用原始方法。请注意,该方法从未被删除或替换,因此通过直接访问接口,原始实现仍然存在。new modifier
当用作修饰符时,new关键字显式隐藏从基类继承的成员
这意味着该方法不会重写虚基类方法,但在派生类的实例上调用时,它仍然优先。换句话说,新方法只影响派生类的变量,而不影响基类
虚拟修改器
virtual关键字用于修改方法、属性、索引器或事件声明,并允许在派生类中重写它
这意味着可以在派生类中重写该方法。在基类变量上调用虚方法时,如果基类变量包含已重写虚方法的派生类实例,则会调用派生类实现。这与new关键字的行为相反。//输出为printrone?为什么?因为只有printrone实现接口