Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Marker interface vs empty abstract class

I am facing difficulties to decide between using a marker interface or an empty abstract class.

I have two classes BrokerResponse and Notification, which have no structural similarity. The only thing connecting them is the need to be subscribable for.

void register(Receivable receivable, BrokerObserver observer)

I somehow dislike using a Marker Interface, because it violates the basic definition of an Interface. On the other hand using an abstract super class would make me as uncomfortable, because both classes have no relationship with one another.

What is the generally preferable approach in this scenario and why?

Edit 1

I forgot to mention, that BrokerResponse is an abstract class itself, that has several subclasses to determine the respective type.

like image 591
tgr Avatar asked Apr 23 '18 09:04

tgr


2 Answers

Abstract class vs. marker interface:

There is nothing wrong with marker interface and there are some use cases for it. Choosing between those two, marker interface has more flexibility.

If you do want to define a type, do use an interface.

An abstract class’s purpose is to provide an appropriate superclass from which other classes can inherit and thus share a common design - your classes don't have common design and nothing to share. Moreover you will stick both of them to some restricted design and will be not so flexible if you will need to add a real different parents to them in the future.

List of use-cases for abstract class:

  • Share code among several closely related classes.

  • Classes that extend your abstract class have many common methods or fields or require access modifiers other than public (such as protected and private).

  • Declare non-static or non-final fields what enables you to define methods that can access and modify the state of the object to which they belong.

Use-cases for interface:

  • Unrelated classes would implement your interface.

  • Specify the behavior of a particular data type, without concerning who implements its behavior.

  • Advantage of multiple inheritances.

All listed arguments are for the usage of interface. Since BrokerResponse is abstract itself and has it's own hierarchy, making the fact that those classes don't have something in common more stronger.

As alternative you can use marker annotation. I would consider to stick one of those two approaches instead of Abstract Class.

Marker interface vs. marker annotation:

According to Joshua Bloch's 'Effective java':

Marker interfaces have two advantages over marker annotations. First and foremost, marker interfaces define a type that is implemented by instances of the marked class; marker annotations do not. The existence of this type allows you to catch errors at compile time that you couldn’t catch until runtime if you used a marker annotation. Another advantage of marker interfaces over marker annotations is that they can be targeted more precisely.

When should you use a marker annotation?

you must use an annotation if the marker applies to any program element other than a class or interface, as only classes and interfaces can be made to implement or extend an interface.

When should you use a marker interface?

Ask yourself the question, Might I want to write one or more methods that accept only objects that have this marking? If so, you should use a marker interface in preference to an annotation. This will make it possible for you to use the interface as a parameter type for the methods in question, which will result in the very real benefit of compile-time type checking.

Summary:

If you want to define a type that does not have any new methods associated with it, a marker interface is the way to go.

If you want to mark program elements other than classes and interfaces, to allow for the possibility of adding more information to the marker in the future, or to fit the marker into a framework that already makes heavy use of annotation types, then a marker annotation is the correct choice.

like image 166
J-Alex Avatar answered Sep 25 '22 19:09

J-Alex


How about annotating them? You got your answer that using a mark interface is the way to go here if you would have to choose, but using an annotation depending on what you might need to do would be much cleaner.

The fact that you say you need to make them somehow "the same" talks about an instanceof call and doing something based on that. The same thing could be achieved via isAnnotationPresent or the like.

But if you add a marker interface, how about making it not a marker interface - only in case you have a finite number of classes you need to test against? Something along the lines of MyInterface {boolean isSubscribable();}

like image 20
Eugene Avatar answered Sep 22 '22 19:09

Eugene