【问题标题】:Breaking virtual invocation using new keyword and again starting a new virtual hierarchy使用 new 关键字中断虚拟调用并再次启动新的虚拟层次结构
【发布时间】:2014-09-28 04:30:32
【问题描述】:

这是我混淆的代码。

 class foo
{
    public string fname;
    public virtual void print()
    {
        Console.WriteLine("I am the boss i am the virtual");
    }
};


class bar : foo 
{

    public override void print()
    {
        Console.WriteLine("I am the first derivative");   
    }
};


class tar : bar
{
    public new virtual void print()
    {

        Console.WriteLine("I am the newly born baby with a new keyword!!!!");
    }

};


class jar : tar
{
    public override void print()
    {
        Console.WriteLine("i am created in derivative of tar i.e, jar");

    }

};  
class Program
{
    static void Main(string[] args)
    {
        foo obj1 = new foo();
        obj1.fname = "neha";

        foo objtar = new jar();  //here lies the confusion why bar print() is called   
        objtar.print();
    }
}

在这段代码中,我使用第三级派生类(jar)对象和基(foo)调用打印方法。看到输出我很困惑

我是一阶导数

谁能解释它背后的原因。我是 c# 的新手,需要帮助....

【问题讨论】:

  • 您使用了new 关键字而不是覆盖。使用new 会破坏继承链。
  • new 是一个棘手的野兽。尝试打印 ((jar)objtar).print()
  • 我知道这可以使用 jar obj = new jar() 来完成。但是我对 jar 的 print() 被调用为什么不在这里调用 foo print() 感到震惊?

标签: c# inheritance polymorphism virtual overriding


【解决方案1】:

这是因为您在 foo 的实例上调用了 printnew 关键字只会应用于该类型的类型化实例。

继承规则不再适用,因为tar.printnew

这是所有记录在案的行为,您可以在 MSDN 上找到。

所以这将按您的预期工作:

jar objtar = new jar();
objtar.print();

【讨论】:

  • 我知道,但是为什么要调用第一个 deived 类方法?为什么不调用基类 print()??
  • 因为您是从bar 派生的,而不是foo。原来的继承链不受new的影响,你只需启动一个新的链。如果用new 声明一个虚方法对基类有任何影响,那么bar 类的编写者将不得不在每个override 可能会或可能不会实际覆盖的假设下设计他的类——即继承将是雷区。
  • 仅仅因为你有overriden 它。 overridenew 有很大的不同。 override 确实遵循继承。
  • @Cygon +1 简单解释了实际原因。谢谢
  • @PatrickHofman 没有帕特里克,我明白了我在寻找虚拟调用链一旦将新的虚拟方法添加到链中就会被破坏,这就是调用 bar print() 的原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-08
  • 2012-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-17
相关资源
最近更新 更多