简体   繁体   中英

Avoid type casting for subclasses

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).

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

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();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM