【问题标题】:Why is can't use overriding method in C#? (not about keyword)为什么不能在 C# 中使用覆盖方法? (不是关于关键字)
【发布时间】:2014-04-26 16:09:25
【问题描述】:
public abstract class A
{
    public void CallMe() { Console.WriteLine("I am A."); }
}

public class B : A
{
    new public void CallMe() { Console.WriteLine("I am B."); }
}

class Program
{
    static void Main(string[] args)
    {
        A a = new B();
        a.CallMe();
    }
}

输出是“我是 A”。

为什么会这样?这合理吗?

由 Visual Studio 2012 编译。

【问题讨论】:

  • 您实际上并没有覆盖,new 关键字隐藏。使用override
  • @user3576363 它没有改变结果,因为您将其称为A 类型。如果您改为使用B b = new B(); b.CallMe();,您将看到B 消息。至于“为什么”它会这样工作,那是因为它就是这样设计的。
  • virtual 在基地
  • "new" 的意思是“我希望这是一种与旧方法同名的新方法,而不是覆盖旧方法”。如果这不是你的意思,请不要那样说。您正在调用旧方法。
  • 编译器已经告诉你你做错了。您添加了“new”来关闭编译器,但这并没有阻止您做错事。下次先google一下错误信息。

标签: c# inheritance overriding


【解决方案1】:

您需要在基类virtual 中创建CallMe() 方法,然后在B 中使用override 修饰符:

public abstract class A
{
    public virtual void CallMe() { Console.WriteLine("I am A."); }
}

public class B : A
{
    public override void CallMe() { Console.WriteLine("I am B."); }
}

【讨论】:

  • @user 它与 Java 没有什么不同。 Java 方法总是虚拟的,除非声明为 final。
【解决方案2】:

B.CallMe() 不会覆盖A.CallMe(),它会隐藏或隐藏A.CallMe()。由于CallMe 是一个非虚拟方法,编译器会根据a 变量的编译时类型来选择调用哪个方法。由于a 的编译时间类型是class A,它会调用A.CallMe()

如果您希望它调用B.CallMe(),您需要在A.CallMe() 上使用virtual 关键字,这将启用虚拟调度,其中应用程序将根据a 的运行时类型调用CallMe() 方法,这是class B

Hiding through inheritance

【讨论】:

  • 它会隐藏或隐藏B.CallMe() 不是这样,而是相反。
猜你喜欢
  • 1970-01-01
  • 2018-05-02
  • 2010-10-18
  • 2012-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多