Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a good design pattern for using an abstract superclass?

When you make a subclass of a class, when do you want to make the superclass abstract because by my knowledge, a superclass can do anything that a abstract class can. Am I right?

By making it abstract, you're just limiting yourself of instantiating the abstract class.

For example, there's two classes, A and B

class A {


}

class B extends A {


} 

and

abstract class A {


}

class B extends A {


} 

Are there any specific difference?

Or, is organizing the code conceptually the whole point of using abstract class as a super class? for example, you want to use abstract class in such a case that each of the subclasses is a more specific type of its abstract superclass (i.e. Fruit > apple, orange, banana, grape, strawberries, etc.) and you want to use non-abstract superclass in a relationship such as Dad and Son?

Can I get a general answer when to use abstract class and when not to? Thanks.

like image 814
chanpkr Avatar asked Mar 21 '23 11:03

chanpkr


2 Answers

If you are not going to use the base class, the abstract class directly, make it abstract.

Such as

public abstract class Shape  {
   ...

You don't care about using a Shape directly, because it can mean anything, so it should be abstract to prevent instantiation. But abstract classes hold important information and functionality about every shape that sub-classes it. Such as the name of the shape, or area or side-count, or whatever.

Sometimes abstract classes don't implement functions because they have no knowledge of how sub-classes might want to do actually handle its processing. Or they know what to do, but simply can't. An example

public abstract class NumberInRange<N extends Number> 
    public abstract boolean isGreaterThanOrEqualToMinBound(N n_n);

A Number can't be directly compared against another, because it's not Comparable. But an int can:

public class IntInRange extends NumberInRange<Integer>  {
   public boolean isGreaterThanOrEqualToMinBound(Integer to_compareTo)  {
      return  (this.compareTo(to_compareTo) >= 0);
   }

So NumberInRange must be abstract, and IntInRange is concrete.


Your question also relates to the issue of abstract-versus-interface. You can inherit multiple interfaces, but you only extend a single class (abstract or not). Interfaces therefore give you more flexibility.

...which brings up the issue of inheritance-versus-composition... but we'll leave that one for later :)

like image 61
aliteralmind Avatar answered Apr 25 '23 02:04

aliteralmind


The main reason is delegation. Interfaces are great for contracts (ie., if you are saying that you implement my interface, these are the things you must do). However, interfaces don't enforce any functionality, just that you are adhering to these method names with such-and-such parameters and return some pre-negotiated type.

Abstraction is a way to provide base functionality and force you to provide implementation details about what you need to accomplish. Abstract classes are very useful when the class can best be put to use as an anonymous class where all but the minutiae details of what happens in the filled-in methods are needed. This pattern is used as adapters for Event handlers in Swing quite extensively.

like image 41
Pedantic Avatar answered Apr 25 '23 02:04

Pedantic