简体   繁体   English

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

[英]Why base class = new derived class cannot call derived class method?

We have two classes A and B, B Derives from A, I created of A a = new B();我们有两个类 A 和 B,B 派生自 A,我创建了A a = new B(); Why in my code when I call method of B that does not contain AI get error.为什么在我的代码中调用不包含 AI 的 B 方法时会出错。 Does it mean that Type Object Pointer is of type A?这是否意味着 Type Object Pointer 是 A 类型? and second why When I call SomeMethod it calls method of A not B?其次,为什么当我调用SomeMethod它调用 A 而不是 B 的方法?

In the heap in this situation when created object instance, type object pointer points to A or 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

    }
}

Because you are missing the glaring warning in the IDE因为您错过了 IDE 中的明显警告

Severity Code Description Project File Line Suppression State Warning CS0108 'B.SomeMethod()' hides inherited member 'A.SomeMethod()'.严重性代码描述项目文件行抑制状态警告 CS0108“B.SomeMethod()”隐藏继承的成员“A.SomeMethod()”。 Use the new keyword if hiding was intended.如果打算隐藏,请使用 new 关键字。

Compiler Warning (level 2) CS0108 编译器警告(级别 2)CS0108

'member1' hides inherited member 'member2'. “member1”隐藏继承的成员“member2”。 Use the new keyword if hiding was intended.如果打算隐藏,请使用 new 关键字。

A variable was declared with the same name as a variable in a base class.变量被声明为与基类中的变量同名。 However, the new keyword was not used.但是,没有使用 new 关键字。 This warning informs you that you should use new;此警告通知您应该使用 new; the variable is declared as if new had been used in the declaration.变量的声明就像在声明中使用了 new 一样。

If you want to hide it, use the new keyword如果要隐藏它,请使用new关键字

However, if you want to call it then use virtual and override it, or just change the method name so you are not hiding it但是,如果您想调用它,请使用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) 虚拟(C# 参考)

The virtual keyword is used to modify a method, property, indexer, or event declaration and allow for it to be overridden in a derived class. virtual 关键字用于修改方法、属性、索引器或事件声明,并允许在派生类中覆盖它们。 For example, this method can be overridden by any class that inherits it:例如,此方法可以被任何继承它的类覆盖:

override (C# Reference) 覆盖(C# 参考)

The override modifier is required to extend or modify the abstract or virtual implementation of an inherited method, property, indexer, or event.需要覆盖修饰符来扩展或修改继承的方法、属性、索引器或事件的抽象或虚拟实现。

Polymorphism (C# Programming Guide) 多态(C# 编程指南)


In the heap in this situation when created object instance, type object pointer points to A or B?在堆这种情况下创建对象实例时,类型对象指针指向A还是B?

You need not worry your self about what happens on the heap (these are implementation details), just what the language allows you to do.您不必担心堆上发生的事情(这些是实现细节),只需担心语言允许您做什么。

However, A technically does not exist, there is only an instance of B, that has all the implementation of A (if you need it)但是,A 在技术上不存在,只有 B 的一个实例,它具有 A 的所有实现(如果需要)

You have to specify that you want to override a virtual function.您必须指定要覆盖虚拟功能。 Try this:尝试这个:

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");
    }
}

To get access to OtherMethod where it's currently failing, you need to tell your A to act like a B .要访问当前失败的其他方法,您需要告诉您的AB一样行事。

Change改变

a.OtherMethod();

to

(a as B).OtherMethod();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM