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 besides being a JSON POJO. As you can see I am using an empty abstract class AbstractResponse
to avoid duplicated code for readResponse()
in the client classes ResponseAClient
and ResponseBClient
.
My question:
Is it bad practice to use an empty abstract class for similar cases and if so, what would be the best way to code this? I have thought about using generics but I've seen many warnings that discourage the use of Java Generics.
Edit: Thanks for the quick response guys. After the useful comments from @Kayaman I'd like to rephrase my question like this:
Is there a better implementation for the kind of situation I've described above than using an empty interface/abstract class. It just seems like bad practice to have an empty interface/abstract class.
Use an interface. There's no sense in using an empty abstract class (unless you want to prevent the classes from subclassing another class).
As for your "many warnings that discourage the use of Java Generics.", I'd be happy to see some links, because that's just not true.
Edit: A generic approach could give you something like the following (Response
is an empty interface for marking concrete response classes and limiting the allowed 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);
}
}
Allowing you to handle responses that are strongly typed.
Client<ResponseA> clientA = new Client<>(ResponseA.class);
ResponseA resp = clientA.readResponse();
So the answer to the question "What's a good alternative to an empty abstract class" is "Refactor and Redesign".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With