【问题标题】:method overriding and method hiding [duplicate]方法覆盖和方法隐藏
【发布时间】:2013-01-16 14:14:47
【问题描述】:

可能重复:
C#: new versus override

class BaseAppXmlLogReaders
    {
        public virtual void WriteLog() { }
        public void Add()
        { 
        }
    }
    class DerivedAppXmlLogReaders : BaseAppXmlLogReaders
    {
        public override void WriteLog()
        {

        }
        public new void Add()
        { }
    }

    class Demo
    {
        public static void Main()
        {
            BaseAppXmlLogReaders obj = new DerivedAppXmlLogReaders();
            obj.Add();//Call base class method
            obj.WriteLog();//call derived class method          
        }
    }

我有点困惑,但是它使 DerivedAppXmlLogReaders 成为对象 但是它调用了基类的 Add() 方法和派生类的 WriteLog() 方法。

【问题讨论】:

  • 问题到底是什么?
  • 是的,你已经覆盖了WriteLog,只是隐藏了Add(以非多态方式)。
  • @Tikkes 我正在创建派生类的对象,但它调用基类方法
  • @Jon 如果我从派生类方法中删除新关键字,那么它会再次调用基类方法..

标签: c# base derived-class


【解决方案1】:

这是因为您将其处理为BaseAppXmlLogReaders。如果您使用以下行,您将调用派生类的 Add 方法。

var obj = new DerivedAppXmlLogReaders(); // or DerivedAppXmlLogReaders obj = ...

编辑:

但是,你仍然可以这样调用派生类的方法:

(obj as DerivedAppXmlLogReaders).Add();

【讨论】:

  • classBase obj =new classDerived();意味着在 new 前面的任何类中创建了派生类的对象,然后创建该类的对象
  • 我知道,但是派生类的成员将被隐藏。
  • 为什么...我没有得到请详细说明
  • 因为它是这样工作的。 Add 方法不是虚拟的,因此它将在持有对象引用的类型上调用(在您的情况下,它是 BaseAppXmlLogReaders)。
【解决方案2】:

如果您调用非虚拟方法,则将调用您所持有的类型的方法,在您的情况下为BaseAppXmlLogReaders。如果您正在调用virtual 方法,框架会将调用指向“正确”的、被覆盖的方法。这就是为什么虚拟呼叫成本略高的原因,以及为什么在 99% 的情况下使用 new 是个坏主意。我还没有看到 new 的合理使用。

【讨论】:

  • classBase obj =new classDerived();意味着在 new 前面的任何类中都创建了派生类的对象,然后创建该类的对象
  • 是的,但是,正如我所说,非虚拟方法将指向 classBase 方法。这是事实,这就是new 的工作原理。 Virtual 告诉运行时检查实际实例中是否有被覆盖的方法,new 方法被忽略,因为基本方法不是 virtual。类上的 sealed 关键字会告诉运行时它不必检查被覆盖的方法,因为不可能有任何方法。如果您可以控制基类,请不要使用 new
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-19
  • 2015-10-17
  • 1970-01-01
相关资源
最近更新 更多