【问题标题】:Abstract class calling an abstract method抽象类调用抽象方法
【发布时间】:2016-05-20 20:36:18
【问题描述】:

谁能向我解释为什么它会这样工作。输出到"Print This"。但是在没有实现的情况下,基类如何调用bar()。

abstract class Base
{
    protected virtual void foo()
    {
        bar();
    }

    protected abstract void bar();
}

class Sub : Program
{
    protected override void foo()
    {
        base.foo();
    }

    protected override void bar()
    {
        Console.WriteLine("Print This");
    }

    static void Main(string[] args)
    {
        Sub obj = new Sub();

        obj.foo();
    }
}

【问题讨论】:

  • Sub 继承 Program 而不是 Bar...错字?

标签: c# inheritance abstract


【解决方案1】:

这就是抽象类的全部意义:它只会作为派生类的实例具体存在。通过声明抽象方法或属性,它只是强制派生类提供这些成员的具体实现。这样,如果你有一个Base 类型的实例,你可以调用myInstance.bar 并且你知道派生类已经实现了它,因为否则它不会编译。

顺便说一下,命名方法时使用pascal大小写,即Foo和Bar。

【讨论】:

    【解决方案2】:

    但是基类怎么调用bar(),没有的时候 实施。

    TL;DR 答案:因为多态性。

    如果你有这个问题,你如何解释这个问题?

    public interface IStuffMaker
    {
        void MakeIt();
    }
    
    public class StuffMaker : IStuffMaker
    {
        public void MakeIt() 
        {
            Console.WriteLine("yeah!");
        }
    }
    
    IStuffMaker maker = new StuffMaker();
    maker.MakeIt();
    

    为什么如果maker 是IStuffMaker 可以调用MakeIt()?因为StuffMaker已经实现了所谓的方法。

    在您的特定情况下,之所以能够调用您的抽象方法,是因为抽象成员是多态,派生类必须重写它以提供实现(与接口成员相同:它们必须实现)。

    抽象类是可能的具体成员(带有主体)和抽象成员的混合,它们只是类似于接口成员的成员签名,但是,与接口相反,由于抽象类可以拥有具体成员,这些可以调用抽象的,因为它们将在派生类中实现。

    【讨论】:

      猜你喜欢
      • 2012-09-21
      • 1970-01-01
      • 2021-10-13
      • 2017-05-02
      • 2016-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多