2

Is there a use case/necessity (from design or implementation perspective) not to make a super class abstract?

Are there any differences in the programming language in use?

To make an example:

abstract class A { /*...*/ }
class B extends A { /*...*/ }

My question is about A: When am I not allowed to use abstract or can I state the Michael Dorner rule: ;)

A good design comes always with an abstract (and not a concrete) superclass.

  • 1
    My question is neither about opinions nor about composition, but concrete use case. The reverse is "Superclasses are (should be) always abstract". Is it true? – Michael Dorner Nov 21 '16 at 14:11
  • 5
    Those use cases are subjective though. In my view, there are no valid use cases for inheritance, thus whether the super class is abstract or not is entirely moot. Others disagree with my "extreme" position on this. – David Arno Nov 21 '16 at 14:14
  • 4
    Also, in Javaland (and others), every class has a non-abstract non-final superclass: Object – Caleth Nov 21 '16 at 16:46
  • Can I down vote your Michael Dorner rule without downvoting the question? – Graham Oct 23 '17 at 15:11
  • You can do whatever you like, but in fact you would down-vote my question, not my rule. But if you disagree I would like to hear your answer why the rule is not a good idea. Of course, I see the practical implications, e.g. for Java. But I don't see a reason until now when or why this rule fails on a theoretical level or as a design maxim. – Michael Dorner Oct 23 '17 at 17:16
5

All the time, you can't avoid it (In Java)

Every class has a non-abstract, non-final superclass: Object.

Rightly or wrongly the designers of Java felt that there were some special actions that should always be available, and always have a default implementation.

Most notably Equals and GetHashCode allow anything to be put into containers and then searched for, by identity.

  • 6
    Wrongly, I'd say. There's no set of operations that every type (object) need share. – gardenhead Nov 22 '16 at 14:36
  • 1
    In Pharo every new class inherits about 400 methods just because its superclass is object. – Adrian Iftode Nov 22 '16 at 21:02
1

In layman's terms:

(I'll use Java in my examples, please extrapolate to your language of choice if possible)

  • There is no superclass modifier. There is a final modifier, though, that prevents anyone ever extending your class.
  • So if I create a concrete class A, I don't know whether someone will extend it in the year 2525. Every non-final class has the potential to become a superclass someday.
  • Come the year 2525 and someone extends my class A

    public B extends A{
    }
    
  • Now A is a superclass. It wasn't a superclass in the beginning. I didn't foresee that someone would extend it in the year 2525.

So the use case for non-abstract superclass is that it was a concrete class (but not yet a superclass) to begin with, you didn't explicitly declared it as final, and someone in the future extended it, making it a superclass.

Another use case is that you want the class to be able to be instatiated and at the same time open for future extension. That's the rationale behind the open/close principle, you can extend concrete classes as well as abstract ones.

Bottom-line: you can't foresee any concrete class not being extended any time, unless you make every concrete class final to prevent it ever becoming another class' superclass. In the other hand I prefer to adhere to the dependency inversion principle that states that no higher components should depend on lower components, both should depend on abstractions.

0

YES, there are cases when the super class should not be abstract. At least in Java's use of the notion of abstract. Whether you make a class abstract or not is circumstantial.

Abstract classes should be used when the class that you're describing is incomplete on its own. For instance:

public abstract class Animal{
    public abstract boolean hasBeak();
}

The above class represents an abstract Animal. In our program we have decided that the important thing about animals is whether they have a beak or not. Obviously, this is dependent on what kind of animal it is. So sub-classes of Animal, Goose, or Bear, for instance will implement the abstract method "hasBeak()" and Goose and Bear are classes which have enough information to implement hasBeak() and return true or false.

The Bear class however may not be abstract. You may have:

public class Bear extends Animal {
    protected location = "The Rockies";

    public boolean hasBeak(){return false;};

    public String getLocation(){return this.location;};
}

This is a case where we have decided that a Bear is not abstract. There is enough information that we want to be able to create instances of the Bear class without any additional information / requirements.

Now we can have:

public class PolarBear extends Bear {
    int sealCount;
    public PolarBear()
    {
        this.location = "The Arctic";
        this.sealCount = 0;
    }

    public void ateSeal()
    {
        this.sealCount++;
    }

    public int getSealCount(){
        return this.sealCount;
    }
}

In this example Bear is indeed a super class, and it is not abstract, and it is valid and meaningful. Here, we want PolarBear to get all the benefits of the code we wrote for Animal and Bear, but how many seals it's eaten is unique to polar bears, so it makes sense to extend bear but for the seal logic / information to be exclusive to the polar bear class.

You may think to yourself, "Right, but your top-level class is still abstract in this example." Yes, but that's only circumstantial. This example is still valid if we remove the Animal class altogether (and remove the extends from the Bear class). Now we have assume a program which exclusively deals with bears, and it's reasonable and valid to have a instantiated Bear object, but it is also a non-abstract super class for the PolarBear class.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.