【问题标题】:What is a good practice to get the correct return class with inheritance?什么是通过继承获得正确返回类的好习惯?
【发布时间】:2021-02-27 13:19:16
【问题描述】:

我有不同类型的用户,他们都继承自父类 User:

class User(string username, string password){...}

class UserAdmin(string username, string password) extends User{
   ...
   // new methods
}

class User(string username, string password) extends User{
   ...
   // new methods
}

我有一种登录方法,但问题是,如果我使用 UserAdmin 的凭据登录,我想返回一个 UserAdmin,对于 User 的所有其他子类也是如此。

public User login(String userName, String password) {
    for (User user : usersList) {
        if (user.isCorrectLogin(userName, password)) {
            return user;
        }
    }
    throw new RuntimeException("Login failed !");
}

我该怎么做?我应该为每种类型的用户设置多个 login() 方法吗?或者是否有不同的方法来设计用户一开始就没有这个问题?

【问题讨论】:

    标签: java oop inheritance design-patterns polymorphism


    【解决方案1】:

    单一登录方法应该适合您的用例,但您应该确保User 的正确类型已经在usersList 中。例如:

    List<User> usersList = new ArrayList<>();
    usersList.add(new User("steve", "some_secret_password"));
    usersList.add(new UserAdmin("bob", "some_even_more_secret_password"));
    

    这样,您现有的login 方法将自动返回正确的类型。

    如果要检查返回值是否属于特定类型,可以使用instanceof 运算符:

    User user = login(username, password);
    if (user instanceof UserAdmin) {
      // Do privileged action
    }
    

    不过,还有其他几种方法可以解决这个问题。您可以简单地让每个特定的用户类型返回它拥有的一组角色,这样您就可以完全避免instanceof

    // User
    public Set<String> getRoles() {
      return Set.of("user");
    }
    
    // UserAdmin
    public Set<String> getRoles() {
      return Set.of("user", "admin");
    }
    

    那么你的逻辑可能变成:

    User user = login(username, password);
    if (user.getRoles().contains("admin")) {
      // Privileged action
    }
    

    【讨论】:

    • 好的,但是如果我想在我的用户类中拥有这些特权操作,我该怎么做呢?
    • 执行instanceof 检查后,您可以将引用转换为正确的类型。 UserAdmin admin = (UserAdmin) user;
    猜你喜欢
    • 2014-04-03
    • 2012-03-11
    • 2018-06-23
    • 1970-01-01
    • 2011-01-10
    • 2019-08-18
    • 2010-09-27
    • 1970-01-01
    • 2014-08-27
    相关资源
    最近更新 更多