简体   繁体   English

避免子类的类型转换

[英]Avoid type casting for subclasses

I have two classes that inherit from the same class:我有两个继承自同一个 class 的类:

ClientUserManager extends UserManager

and

ServerUserManager extends UserManager

UserManager is abstract. UserManager 是抽象的。

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() .但是,我的每个子类都应该能够使用它们的UserService专业化( ClientUserServiceServerUserService ),正如您已经从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).附带信息:为了证明为什么我想同时概括事物并保持专业化(正如 Oğuzhan Aslan 已经指出的那样),让我说我使用了一个依赖注入框架(Dagger 2),它为我提供了相同的“关键"/superclass,相应的实现作为回报(这里是客户端或服务器)。

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.你有一个上下文(UserManager),它应该得到一些特定的策略(UserService)并使用它。

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:一种选择是使用 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();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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