Abstract class calling an abstract method

2019-09-21 11:55发布

问题:

Can anyone explain to me why this works the way it does. The output comes out to "Print This". But how does the base class call bar(), when there is no implementation.

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

回答1:

That's the whole point of an abstract class: that it will only ever exist concretely as an instance of the derived class(es). By declaring abstract methods or properties, it is simply forcing the derived class(es) to provide concrete implementations of those members. In this way, if you have an instance of type Base, you can call myInstance.bar and you know that the derived class has implemented it because it wouldn't compile otherwise.

By the way, use pascal case when naming methods, i.e. Foo and Bar.



回答2:

But how does the base class call bar(), when there is no implementation.

TL;DR answer: because of polymorphism.

If you got this question, how do you explain this?

public interface IStuffMaker
{
    void MakeIt();
}

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

IStuffMaker maker = new StuffMaker();
maker.MakeIt();

Why if maker is IStuffMaker can call MakeIt()? Because StuffMaker has implemented the so-called method.

In your particular case the reason behind being able to call your abstract method is because an abstract member is polymorphic and a derived class must override it to provide an implementation (same as interface members: they must be implemented).

Abstract classes are a mix of possible concrete members (with body) and abstract ones, which are just member signatures like interface members, but, in opposite to interfaces, since abstract classes can own concrete members, these can call abstract ones because they will be implemented in a derived class.