Чем в java заменить множественное наследование?
Хочу реализовать приблизительно следующую архитектуру:

Пояснение:
Base- Что-то вроде сущности-хранилища, в котором хранятся какие-то базовые объекты;ChildN- потомки, реализующие свой спектр действий над данными, которые хранятся в классеBase. По сути являются интерфейсами, т.к. никакого состояния не хранят;static Mixin- класс, объединяющий в себе все методы изChildN. Коллизий между именами методов нет. Все его методы (т.е. методы, унаследованные отChildN) должны быть статическими, вызываться без инстанцирования.
В python эта задача легко бы решилась множественным наследованием, в java такого нет. Как быть?
Примерный псевдокод того, что хочу реализовать:
class Base {
static protected final String someString = "01";
}
class Child1 extends Base {
static public char get_0() {
return someString.charAt(0);
}
}
class Child2 extends Base {
static public char get_1() {
return someString.charAt(1);
}
}
class MixIn extends Child1, Child2 { // Так сделать нельзя
}
public class Main {
public static void main(String[] args) {
System.out.println(MixIn.get_0()); // Итоговое использование должно быть таким
System.out.println(MixIn.get_1());
}
}
Ответы (1 шт):
Как выяснилось, разделение функционала на несколько классов с повторным объединением в один нужно вам исключительно в целях логической группировки. Возможные решения вашей проблемы:
Использование интерфейсов
Вы можете сделать child-ы интерфейсами. В Java нет множественно наследования, зато можно имплементировать несколько интерфейсов. Чтобы сделать реализацию методов прямо в интерфейсах (чтобы они не требовали реализации в реализующем их классе), можно использовать ключевое слово default:
class Base {
static public final String str = "01";
}
interface Child1 {
default char get0() {
return Base.str.charAt(0);
}
}
interface Child2 {
default char get1() {
return Base.str.charAt(1);
}
}
class MixIn implements Child1, Child2 {
}
class Main {
public static void main(String[] args) {
MixIn mixIn = new MixIn();
System.out.println(mixIn.get0());
System.out.println(mixIn.get1());
}
}
Отказ от разделения функционала
Вы работаете с одним репозиторием Base. На мой взгляд здесь более чем достаточно использование одного класса без всяких интерфейсов. Более того, можно все эти методы разместить в классе Base.
Например:
class Base {
private final String str = "01";
public String getStr() {
return str;
}
}
class MixIn {
private Base base;
public MixIn(Base base) {
this.base = base;
}
public char get0() {
return base.getStr().charAt(0);
}
public char get1() {
return base.getStr().charAt(1);
}
}
public class Main {
public static void main(String[] args) {
MixIn mixIn = new MixIn(new Base());
System.out.println(mixIn.get0());
System.out.println(mixIn.get1());
}
}
Использование статических внутренних классов
Вы говорите, что вам нужна логическая группировка. В Java существует конструкция, которая называется статический внутренний или вложенный класс. Внутри класса создаётся ещё один класс, который отмечается static. Таким образом вы можете достичь логической группировки. Пример:
class Base {
static public final String someString = "01";
}
class MixIn {
public static class Child1 {
static char get1() {
return Base.someString.charAt(1);
}
}
public static class Child2 {
static char get0() {
return Base.someString.charAt(0);
}
}
}
Видите, я создал общий класс MixIn, а внутри него два статических класса. Вызываются они вот так:
class Main {
public static void main(String[] args) {
System.out.println(MixIn.Child1.get1());
System.out.println(MixIn.Child2.get0());
}
}
Как видите, никакого инстанцирование нет, а классы/методы логически сгруппированы.