为什么基类=新派生类不能调用派生类方法?

时间:2019-01-03 23:15:33

标签: c# inheritance clr

我们有A和B两类,B源自A, 我创建了A a = new B(); 为什么在我的代码中调用不包含A的B方法时出现错误。 这是否意味着类型对象指针是A类型?其次,为什么当我调用SomeMethod时,它调用的是A而不是B的方法?

在这种情况下在堆中创建对象实例时,类型对象指针指向A还是B?

class A
{
    public void SomeMethod()
    {
        Console.Write("This is A");
    }
}

class B : A
{
    public void SomeMethod()
    {
        Console.Write("This is B");
    }

    public void OtherMethod()
    {
        Console.Write("This is New method");
    }
}
class Program
{
    static void Main(string[] args)
    {
        A a = new B();

        a.SomeMethod(); // This is A method
        a.OtherMethod(); // I get error here that a does not contain definition for this method

    }
}

3 个答案:

答案 0 :(得分:2)

因为您没有在IDE中看到明显的警告

  

严重性代码描述项目文件行抑制状态   警告CS0108'B.SomeMethod()'隐藏继承的成员   'A.SomeMethod()'。如果打算隐藏,请使用new关键字。

Compiler Warning (level 2) CS0108

  

'member1'隐藏继承的成员'member2'。如果使用新关键字   隐藏是故意的。

     

声明一个变量,其名称与基变量相同   类。但是,未使用new关键字。此警告通知您   您应该使用new将该变量声明为好像已经有new   在声明中使用。

如果要隐藏它,请使用new关键字

但是,如果要调用它,请使用virtualoverride,或者只是更改方法名称以免隐藏它

class A
{
   public virtual void SomeMethod()
   {
      Console.Write("This is A");
   }
}

class B : A
{
   public override void SomeMethod()
   {
      base.SomeMethod();
      Console.Write("This is B");
   }

   public void OtherMethod()
   {
      Console.Write("This is New method");
   }
}

virtual (C# Reference)

  

virtual关键字用于修改方法,属性,索引器或   事件声明,并允许其在派生中被覆盖   类。例如,该方法可以被任何   继承它:

override (C# Reference)

  

需要override修饰符来扩展或修改摘要或   继承的方法,属性,索引器或   事件。

Polymorphism (C# Programming Guide)


  

在这种情况下的堆中创建对象实例时,键入   对象指针指向A还是B?

您不必担心堆上会发生什么(这些是实现细节),而不必担心语言允许您做什么。

但是,从技术上讲,A不存在,只有B的实例具有A的所有实现(如果需要)

答案 1 :(得分:0)

您必须指定要覆盖虚拟功能。 试试这个:

class A
{
    public virtual void SomeMethod()
    {
        Console.Write("This is A");
    }
}

class B : A
{
    public override void SomeMethod()
    {
        Console.Write("This is B");
    }

    public void OtherMethod()
    {
        Console.Write("This is New method");
    }
}

答案 2 :(得分:0)

要访问当前失败的OtherMethod,您需要告诉AB一样行事。

更改

a.OtherMethod();

(a as B).OtherMethod();