IMO-наследование - не лучший способ смоделировать это, вместо этого я бы попробовал композицию.
У вас может быть класс Person и несколько классов Role (реализующих общий интерфейс или являющихся членами перечисления Role, в зависимости от контекста), с каждым человеком, к которому прикреплена одна или несколько ролей.
Таким образом, вы можете легко добавлять новые типы ролей и динамически присоединять / отсоединять роли от человека. (Вы также можете иметь людей без роли, если возникнет такая необходимость.)
Грубый пример:
interface Role {
...
}
final class Client implements Role {
...
}
final class Provider implements Role {
...
}
final class Agent implements Role {
...
}
class Person {
List<Role> roles;
public void addRole(Role role) { ... }
public void removeRole(Role role) { ... }
public Role getRoleOfType(Class<? extends Role> roleType) { ... }
}
Обновление: пример на основе enum
Это применимо, если объекты роли не имеют состояния, поэтому вы присоединяете одинаковые экземпляры роли к каждому человеку.
enum Role {
CLIENT,
PROVIDER,
AGENT;
// possible members, constructor etc.
}
Класс Person почти такой же, как указано выше, за исключением того, что
- Я использую
EnumSet
вместо List
, так как это специально для перечислений,
getRoleOfType()
здесь не имеет смысла, поэтому я заменил его на hasRole()
.
class Person {
Set<Role> roles = new EnumSet<Role>();
public void addRole(Role role) { ... }
public void removeRole(Role role) { ... }
public boolean hasRole(Role role) { ... }
}