Lately I was a few times asked a question "what do we need abstract classes for?"

And today I've got one more question, which inspired me to write this.

Let us have a task to write an application, which will perform some simple arithmetic operations on numbers, represented in a different numeric systems.

For example, our program should be able to add numbers in roman, arabic and hexadecimal systems. But later we should be able to add more operations, like division, multiplication and subtraction.

This is where an abstract class comes to help us!

Rather than write an interface Number, which will define the addition operator and then implementing it for each class like RomanNumber and HexadecimalNumber we will better use an abstract class, which will be able to add decimal numbers and will declare abstract method to convert number itself to decimal system.

Take a look:

public interface INumber {
    public INumber add(INumber other);
}

public class RomanNumber implements INumber {
    public RomanNumber add(INumber other) {
        // when `other` is not a RomanNumber
        // convert other to RomanNumber
        // add `other` to `this`
    }
}

public class HexadecimalNumber implements INumber {
    public HexadecimalNumber add(INumber other) {
        // convert other to HexadecimalNumber and add...
    }
}

…and compare it to this:

public abstract class Number {
    public abstract Integer toDecimal();
    public abstract Number fromDecimal(Integer);

    public Number add(Number other) {
        returh fromDecimal(this.toDecimal() + other.toDecimal());
    }
}

public class RomanNumber extends Number {
    public Integer toDecimal() {
        // convert `this` to Integer
    }

    public RomanNumber fromDecimal(Integer n) {
        // convert `n` to RomanNumber
    }
}

public class HexadecimalNumber extends Number {
    public Integer toDecimal() {
        // convert `this` to Integer
    }

    public HexadecimalNumber fromDecimal(Integer n) {
        // convert `n` to HexadecimalNumber
    }
}

This is how we can create an abstraction: we can add or perform any other arithmetic operations regardless on which numeric system we use!