What is a good alternative to using an empty abstract class?

Suppose I have the following:

public abstract class AbstractResponse { // this class is totally empty! } public class ResponseA extends AbstractResponse { // JSON POJO } public class ResponseB extends AbstractResponse { // JSON POJO } public abstract class AbstractClient { public abstract Class getType(); public AbstractResponse readResponse() { ObjectMapper mapper = new ObjectMapper(); AbstractResponse response; try { return (AbstractResponse) mapper.readValue(data, getType()); } catch (IOException e) {...} } } public class ResponseAClient extends AbstractClient { public Class getType() { return ResponseA.class; } } public class ResponseBClient extends AbstractClient { public Class getType() { return ResponseB.class; } } 

ResponseA and ResponseB have nothing in common except JSON POJO. As you can see, I use the empty AbstractResponse abstract class to avoid code duplication for readResponse() in the ResponseAClient and ResponseBClient client classes.

My question is :

The wrong practice of using an empty abstract class for such cases, and if so, what is the best way to encode this? I was thinking about using generics, but I have seen many warnings that prevent the use of Java Generics.

Edit: Thanks for the answers. After helpful comments from @Kayaman, I would like to rephrase my question as follows:

Is there a more efficient implementation for the situation described above than using an empty interface / abstract class. It just seems like bad practice has an empty interface / abstract class.

+4
source share
2 answers

Use the interface. It makes no sense to use an empty abstract class (unless you want the classes to carry subclasses of another class).

As for your “many warnings that prevent the use of Java Generics,” I would be happy to see some links because it just isn't.

Edit: a generic approach might give you something like the following ( Response is an empty interface for marking specific response classes and restricting valid types that Client can handle)

 public class Client<T extends Response> { private Class<T> clazz; public Client(Class<T> clazz) { this.clazz = clazz; } public T readResponse() { ObjectMapper mapper = new ObjectMapper(); return (T) mapper.readValue(data, clazz); } } 

Allows you to process responses that are strongly typed.

 Client<ResponseA> clientA = new Client<>(ResponseA.class); ResponseA resp = clientA.readResponse(); 

So, the answer to the question “What a good alternative to an empty abstract class” is “Refactoring and redesign”.

+14
source

Instead of using an empty interface or abstract class, I would rather use annotation with @Retention(RetentionPolicy.RUNTIME) . This is a bit more code to write, although it may not be particularly readable and fast (the part where you want to check if the class has this annotation).

The language has empty interfaces, for example Serializable . But since Java 5 doesn't make much sense.

 import java.io.IOException; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; public abstract class AbstractClient { public abstract Class getType(); public Object readResponse() { ObjectMapper mapper = new ObjectMapper(); try { Object response = mapper.readValue(data, getType()); if (response.getClass().getDeclaredAnnotation(Response.class) == null) { // Not a valid type } return response; } catch (IOException e) {...} } } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @interface Response { } @Response class ResponseA extends AbstractResponse { // JSON POJO } @Response class ResponseB extends AbstractResponse { // JSON POJO } class ResponseAClient extends AbstractClient { public Class getType() { return ResponseA.class; } } class ResponseBClient extends AbstractClient { public Class getType() { return ResponseB.class; } } 
0
source

All Articles