Virtual methods without body

2019-06-14 21:46发布

问题:

I was looking at some code in an abstract class:

public virtual void CountX(){}

public virtual void DoCalculation() { ...code}

Why should I declare an empty virtual method in an abstract class if it is not mandatory to override it in derived types?

回答1:

As @Adam told you, there are many cases in which it makes sense. When you create an abstract class, it's because you want to create a common interface for all classes deriving from that one; however, at that level of inheritance you won't have enough information to be able to create working code for that method.

For example, if you create the class Figure, with the getArea() method, you won't be able to write code that is going to correctly calculate the area for all figures. You'll have to wait to write the code for Rectangle, or Circle (both deriving from Figure), in order to be able to write working code for them.



回答2:

Because if the default behaviour is to do nothing, but derived classes might want to do something. It's a perfectly valid structure.

It allows your base code to call it. You tend to see similar designs when there is "BeforeXXX" and "AfterXXX" code, at the base class this code is empty, but the method needs to be there to compile. In derived classes, this code is optional, but needs to be virtual to be overridden.

The fact that it is in an abstract class shouldn't confuse its behaviour.

An example:

  abstract class Base
    {
        public void ProcessMessages(IMessage[] messages)
        {
            PreProcess(messages);

            // Process.

            PostProcess(messages);
        }

        public virtual void PreProcess(IMessage[] messages)
        {
            // Base class does nothing.
        }

        public virtual void PostProcess(IMessage[] messages)
        {
            // Base class does nothing.
        }
    }

    class Derived : Base
    {
        public override void PostProcess(IMessage[] messages)
        {
            // Do something, log or whatever.
        }

        // Don't want to bother with pre-process.
    }

If these methods (Pre, Post) were abstract, then all derived classes would need to implement them (likely as empty methods) - code litter that can be removed using empty virtual methods at the base.



回答3:

If it is MANDATORY to override and no default logics could be written in base class, than virtuality is wrong and method should be abstract. If the default action is to do nothing, than as Adam mentioned, making empty virtual method in base class is perfectly valid structure



回答4:

When you declare the method as abstract, the inherited class has to override that method (provide an implementation). It is mandatory.

When the method is declared as virtual, the inheritor can override the method and provide an implementation other than the default.



回答5:

From a design perspective this smells bad and indicates that the implementation of the design is in an immature state. If a method is not required by every class that derives a particular base class then by definition it does not belong in the base class. You will usually discover that this method is used by particular derivations of the base class and that indicates a new interface or layer of abstraction in your inheritance hierarchy.