Reputation: 1893
I have two classes that inherit from the same class:
ClientUserManager extends UserManager
and
ServerUserManager extends UserManager
UserManager is abstract.
public abstract class UserManager {
protected final UserService userService;
public UserManager(UserService userService) {
this.userService = userService;
}
As an example, the server subclass:
public class ServerUserManager extends UserManager {
public ServerUserManager(UserService userService) {
super(userService);
}
public void someMethod() {
((ServerUserSerivice)userService).doSomethingForSERVERONLY();
}
However, my sub-classes should each be able to use their specializations of UserService
(ClientUserService
or ServerUserService
), as you can already see from someMethod()
. I would like to be able to do without the constant typecasting.
Is there a more elegant or generic solution?
Side info: To justify why I want to both generalize things and keep specializations at the same time (as Oğuzhan Aslan already pointed out), let me say that I use a dependency injection framework (Dagger 2) which gives me for the same "key"/superclass, the respective implementation in return (here client or server).
Upvotes: 0
Views: 232
Reputation: 21
One option is to use generics:
public abstract class UserManager<T extends UserService> {
protected final T userService;
public UserManager(T userService) {
this.userService = userService;
}
}
public class ServerUserManager extends UserManager<ServerUserService> {
public ServerUserManager(ServerUserService userService) {
super(userService);
}
public void someMethod() {
userService.doSomethingForSERVERONLY();
}
}
Upvotes: 2
Reputation: 5828
I'm not entirely clear what you are trying to achieve but I will suggest in general to try and use design patterns according to your use case.
This one seems similar to a "Strategy Pattern". You have a context (UserManager) that should get some specific strategy (UserService) and use it.
For example:
public interface UserService {
public void execute();
}
public class ServerUserService implements UserService {
public void execute(){
//does something for server
};
}
class ServerUserManager {
private UserService userService;
public ServerUserManager(UserService userService) {
this.userService = userService;
}
public void doSomething() {
return this.userService.execute();
}
};
You can google "Strategy Pattern" to see different flavours of implementation
Upvotes: 1