首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >超类的公共非虚拟成员干扰子类中的重写的设计原理

超类的公共非虚拟成员干扰子类中的重写的设计原理
EN

Stack Overflow用户
提问于 2013-01-25 17:40:07
回答 3查看 74关注 0票数 1

这背后的设计原理是什么:

好的:

代码语言:javascript
复制
public class A
{
    public virtual void DoWork() { Console.WriteLine("A"); }
}
public class B : A
{
    private new void DoWork() { Console.WriteLine("B"); } //private works
}
public class C : B
{
    public override void DoWork() { Console.WriteLine("C"); }
}

错误:

代码语言:javascript
复制
public class A
{
    public virtual void DoWork() { Console.WriteLine("A"); }
}
public class B : A
{
    public new void DoWork() { Console.WriteLine("B"); } //public doesn't
}
public class C : B
{
    public override void DoWork() { Console.WriteLine("C"); }
}

为什么非虚方法会干扰覆盖虚方法呢?

编辑:更多解释。第一种情况:编译器检查方法是私有的(新的),因此它允许类C.DoWork()覆盖类A.DoWork() (不混合虚拟和非虚拟(B.DoWork())方法)。第二种情况:编译器看到public (new) void被声明,并且它任意地(?)类中的中断重写。现在,如果我想声明新的虚拟DoWork(),我可以这样做,如果我不想重写,我可以使用密封说明符。但在本例中,我编写了public void DoWork()来声明正常的非虚方法,并且我不希望它像在私有情况下那样参与虚拟继承链。在第二个示例中,我期望:

代码语言:javascript
复制
A ac = new C();
ac.DoWork();

来打印C,就像在私人案例中一样。

EN

回答 3

Stack Overflow用户

发布于 2013-01-25 17:42:53

在第一个示例中,您的C类ovverides A的DoWork (B有DoWork,它是私有的,对子类不可见)。在第二个例子中,你通过非虚函数隐藏了DoWork,编译器抱怨你试图覆盖非虚函数。解决方案是公开虚拟函数族。通过new virtual,可以在这些族之间创建分隔。

代码语言:javascript
复制
public class B : A
{
    public new virtual void DoWork() { Console.WriteLine("B"); } //private works
}

然后这段代码

代码语言:javascript
复制
A a = new C();
a.DoWork();

打印A

代码语言:javascript
复制
B b = new C();
b.DoWork();

打印C

您可以更详细地阅读如何在Knowing When to Use Override and New Keywords中使用new virtual。没有virtualnew关键字具有与new virtual不同的语义,您可以在new keyword in method signature上阅读有关它的更多信息。

票数 0
EN

Stack Overflow用户

发布于 2013-01-25 17:46:48

因为在第一种情况下,您覆盖的是A类函数而不是B类函数

代码语言:javascript
复制
public class A
{
    public virtual void DoWork() { Console.WriteLine("A"); }
}
public class B : A
{
    private new void DoWork() { Console.WriteLine("B"); } //private works
}
public class C : B
{
    public override void DoWork() { Console.WriteLine("C"); } //OVERRIDES A.DoWork()
}

不能重写基类的 virtual/abstract方法。

票数 0
EN

Stack Overflow用户

发布于 2013-01-25 17:55:13

在以下代码中

代码语言:javascript
复制
public class A
{
    public virtual void DoWork() { Console.WriteLine("A"); }
}
public class B : A
{
    private new void DoWork() { Console.WriteLine("B"); } //private works
}
public class C : B
{
    public override void DoWork() { Console.WriteLine("C"); }
}

您告诉编译器B类中的DoWork()方法是A类的DoWork()方法的new版本。然而,它允许你在C中私有DoWork,因为你在B中声明DoWork的new版本是私有的,这使得编译器假设该方法不会暴露给外部世界。

然而,在这方面,

代码语言:javascript
复制
public class A
{
    public virtual void DoWork() { Console.WriteLine("A"); }
}
public class B : A
{
    public new void DoWork() { Console.WriteLine("B"); } //public
}
public class C : B
{
    public override void DoWork() { Console.WriteLine("C"); }
}

您告诉编译器使用新版本的方法DoWork(),从编译器的角度来看,这有点错误,因为它不能根据设计语言时设置的规则对非abstract/virtual/overriden方法执行override

我认为,这就是为什么你的代码在一种情况下会出错,而在另一种情况下不会。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14519053

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档