#java #oop #inheritance #design-patterns #polymorphism
#java #ооп #наследование #шаблоны проектирования #полиморфизм
Вопрос:
У меня разные типы пользователей, все они наследуют от родительского класса 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
}
У меня есть метод для входа в систему, но дело в том, что если я войду в систему с учетными данными администратора пользователя, я хочу вернуть администратора пользователя, то же самое для всех других дочерних классов 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() для каждого типа пользователей? Или есть другой способ настроить пользователей так, чтобы у них не было этой проблемы в первую очередь?
Ответ №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
}
Комментарии:
1. Хорошо, но если я хочу иметь эти привилегированные действия внутри своих пользовательских классов, как я могу это сделать?
2. После выполнения
instanceof
проверки вы можете привести ссылку к нужному типу.UserAdmin admin = (UserAdmin) user;