Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I was recently looking through some open source code PicketLink code. If you take a look at this class, you'll see a number of concrete methods in an abstract class that do nothing. Is there any purpose whatsoever for this?

I thought about two things:

  1. If the method needs to be overriden by subclasses and not defined in the parent abstract class, why not simply make it abstract?
  2. If only some of the child classes actually need to implement the method, wouldn't this indicate the need for a restructuring of the class hierarchy so that children are not forced to have methods that are not applicable?
like image 454
josh-cain Avatar asked Dec 07 '12 20:12

josh-cain


People also ask

Can there be concrete methods in abstract class?

Abstract classes are similar to interfaces. You cannot instantiate them, and they may contain a mix of methods declared with or without an implementation. However, with abstract classes, you can declare fields that are not static and final, and define public, protected, and private concrete methods.

What is the use of concrete method in abstract class?

A concrete method means, the method has complete definition but it can be overridden in the inherited class. If we make this method "final" then it can not be overriden. Declaring a method or class "final" means its implementation is complete.

Do abstract methods have to be empty?

abstract method bodies must be empty (no curly braces) subclasses must implement the abstract class's abstract methods.

What is the benefit of making an empty abstract method in a base class?

It allows you to add abstract methods to your superclass (and implementations to the subclasses) later, without affecting any existing clients. The abstract keyword works even if the non-leaf class does not currently have any abstract methods.


3 Answers

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

like image 83
Andrés Fortier Avatar answered Oct 06 '22 00:10

Andrés Fortier


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
{
}
like image 27
PeteGO Avatar answered Oct 06 '22 02:10

PeteGO


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.

like image 21
Thorn G Avatar answered Oct 06 '22 01:10

Thorn G