Is there any reason for an empty concrete method in an abstract class?

对着背影说爱祢 提交于 2019-11-30 21:34:55

While not the most common case, sometimes it is handy in the context of a template method. In this case there is a method that defines the flow, leaving the concrete implementation of some parts to its subclasses. In some cases a default concrete behavior is to do nothing, leaving the concrete method in the base class empty, but allowing customization in the subclass by overriding it.

HTH

Personally I think it is a code smell.

Like you say, unless they have some base functionality - which they don't, they should be abstract, forcing derived classes to provide implementation.

If some derived classes shouldn't have an implementation for these methods, then there's probably something wrong with the design.

Consider this:

public abstract class Animal
{
    public abstract string Speak();
}

public class Dog : Animal
{
    public override string Speak()
    {
        Console.WriteLine("Woof");
    }
}

public class Cat : Animal
{
    public override string Speak()
    {
        Console.WriteLine("Meow");
    }
}

All fine so far, but what if you want to add an animal that doesn't speak?

public class Ant : Animal
{
    public override string Speak()
    {
        // do nothing - ants don't speak.
    }
}

This in my opinion is bad. Someone might do this (what you have described).

public abstract class Animal
{
    public string Speak()
    {
        // not abstract because not all derived animals speak.
    }
}

This in my opinion, is better, but still not great. What I would like to see in this situation is either Speak be moved to an interface and only the animals that can speak implement it, or something like this.

public abstract class Animal
{
}

public abstract class Mammal : Animal
{
    public abstract string Speak();
}

public class Dog : Mammal
{
    public override string Speak()
    {
        Console.WriteLine("Woof");
    }
}

public class Cat : Mammal
{
    public override string Speak()
    {
        Console.WriteLine("Meow");
    }
}

public class Ant : Animal
{
}

Building off of Andres Fortier's answer, you will also see this pattern a lot in Swing, with the various EventListener Adapter classes. For example, MouseAdapter provides corresponding empty methods for each listener method. This allows the interface to define all relevant methods, but implementations to extend the corresponding adapter and only override a single method they care about, instead of being forced to provide empty bodies for all other interface methods.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!