是否存在派生类应隐藏的情况?

flo*_*ode 4 c# polymorphism

也许是一个愚蠢的问题,但假设 base class A定义了virtual method V一个问题,那么 通过声明一个具有相同签名的新的derived class C隐藏条件A.V是有意义的 :virtual method C.VA.V

class Program
{
    static void Main(string[] args)
    {
        A a = new C();
        a.Print(); // prints "this is in B class"

        C c = new C();
        c.Print();// prints "this is in C class"
    }
}

class A
{
    public virtual void Print()
    {
        Console.WriteLine("this is in A class");
    }
}

class B:A
{
    public override void Print()
    {
        Console.WriteLine("this is in B class");
    }
}

class C : B
{
    public virtual void Print()
    {
        Console.WriteLine("this is in C class");
    }
}
Run Code Online (Sandbox Code Playgroud)

谢谢

dth*_*rpe 8

隐藏继承的虚拟不是作为有意设计的一部分而应该完成的事情.语言支持虚拟隐藏,使对象框架对未来的变化更具弹性.

示例:对象框架X的第1版不提供Print()函数.Bob决定通过在他自己的后代类中定义Print()函数来扩展一些框架X对象.由于他计划在更具体的类中覆盖它们,因此他还使Print()函数成为虚拟的.

之后,发布了对象框架X的第2版.Bob决定升级他当前的项目以使用Release 2而不是Release 1.对于Bob来说,对象框架X团队还决定Print()将是一个有用的功能,因此他们在其中一个中添加了一个虚拟的Print().框架的基类.

使用虚拟隐藏,包含Bob的Print()实现的Bob的后代类应该编译并运行正常,即使基类中现在存在不同的Print() - 即使使用不同的方法签名.知道基类Print()的代码将继续使用它,知道Bob的Print()的代码将继续使用它.这两个人永远不会见面.

没有虚拟隐藏,Bob的代码根本不会编译,直到他对他的源代码进行一些非平凡的手术以消除Print()上的名称冲突.有人会认为这是"正确"的事情(拒绝编译),但实际上,任何需要修改现有工作代码的基础库的修改都不会与客户完全一致.他们会责怪破坏一切的框架,并且说不好.

鲍勃得到关于基本打印被Bob的打印模糊的编译器警告是合理的,但这不是致命的错误.Bob应该尽快清理(通过重命名或删除他的Print()函数)以避免人为混淆.