It has conceptual meaning: this class has behavior that in itself does not make sense.
Of course, it is difficult to imagine such a scenario without clearly defined extension points (i.e. abstract methods), but sometimes it will be a fairly accurate model of your problem.
You might have something like this:
public abstract class ObjectWithId { private final String id; public ObjectWithId( String id ) { this.id = id; } public final String getId() { return id; } }
And then you can expand it to declare different types of objects with identifiers. Here you have a completely defined and implemented behavior, but no restrictions on any other subclasses of behavior may appear.
Note that a much simpler way to model the same thing is to use composition instead of inheritance.
public final class ObjectWithId<T> { private final String id; private final T ob; public ObjectWithId( String id, T ob ) { this.id = id; this.ob = ob; } public String getId() { return id; } public T getObject() { return ob; } }
But before generics were introduced (up to Java 1.4), it would not be so elegant and clearly better than an abstract class solution, because you would have to trade type security.
source share