Есть ли способ подражать миксинам или чертам в java? в принципе, мне нужен способ сделать множественное наследование, поэтому я могу добавить общую бизнес-логику к нескольким классам
Java черты или шаблон mixins?
Ответ 1
Я бы инкапсулировал всю бизнес-логику в новый класс BusinessLogic
и имел бы каждый класс, которому нужно BusinessLogic
делать вызовы для класса. Если для ваших классов, которые вызывают вызовы BusinessLogic
, вам нужна одиночная иерархическая иерархия, вам также придется создать интерфейс (BusinessLogicInterface
?)
В псевдокоде:
interface BusinessLogicInterace
{
void method1();
void method2();
}
class BusinessLogic implements BusinessLogicInterface
{
void method1() { ... }
void method2() { ... }
}
class User
extends OtherClass
implements BusinessLogicInterface
{
BusinessLogic logic = new BusinessLogic();
@Override
void method1() { logic.method1(); }
@Override
void method2() { logic.method2(); }
}
Это не самая красивая реализация для работы с отсутствием множественного наследования, и она становится довольно громоздкой, когда интерфейс имеет множество методов. Скорее всего, вы захотите попробовать и переконфигурировать свой код, чтобы избежать необходимости микширования.
Ответ 2
Не так, как вы хотите это сделать. Эффективная Java рекомендует, чтобы вы "любили композицию над наследованием". Это означает, что вы перемещаете общую логику на другие классы и делегируете. Вот как вы обходите отсутствие множественного наследования в java.
Ответ 3
Является ли объект-пурист в вас сегодня?
Думаете, вы могли бы сделать с небольшим композитным ориентированным программированием?
Затем вы, сэр, ищете Apache Polygene (ранее Qi4J или Zest);)
Ответ 4
Ответ Java на множественное наследование - это возможность реализовать несколько интерфейсов. Конечно, это означает, что вы получите декларации метода, но не логику.
Вы можете попробовать эмуляцию mixins по составу: ваш Java-класс может определять переменные-члены, которые представляют другие классы, которые выполняют некоторую общую бизнес-логику.
При разработке классов Java я не нашел недостатка в множественном наследовании стиля С++, чтобы препятствовать дизайну моей архитектуры. Вы найдете способ добиться того, что вы хотите сделать.
Ответ 5
QI4J позволяет использовать mixins
Ответ 6
Вы можете использовать тот факт, что интерфейсы позволяют вложенным классам (автоматически public static) поддерживать стандартную реализацию методов интерфейса, инкапсулированных в самом интерфейсе. То есть переместите класс BusinessLogic примера Alex B внутри интерфейса.
Это похоже на способ Scala генерирует JVM-код для признаков, как описано здесь Как Scala скомпилированы в байт-код Java?
При этом пример будет выглядеть следующим образом:
interface BusinessLogicInterface {
void method0();
class DefaultImpl {
private DefaultImpl() {
}
public static void method1(BusinessLogicInterface self) { ... }
public static void method2(BusinessLogicInterface self) { ... }
}
void method1();
void method2();
}
class User extends OtherClass implements BusinessLogicInterface {
@Override
void method0() { ... }
@Override
void method1() { BusinessLogic.defaultImpl.method1(this); }
@Override
void method2() { BusinessLogic.defaultImpl.method2(this); }
}
Обратите внимание, что мы передаем объект типа интерфейса как параметр "self". Это означает, что бизнес-логика может использовать другие абстрактные методы (method0). Это может быть очень полезно для создания признака с абстрактными методами, которые все ортогональны друг другу и методами "расширения" полезности, которые могут быть реализованы в терминах этих ортогональных методов.
Недостатком является то, что каждый интерфейс должен копировать/вставлять код делегирования шаблона. Другой часто используемый шаблон в Java без этого недостатка (но с меньшей связностью и меньшим количеством способов OO для вызова методов) заключается в создании класса с множественным именем в качестве интерфейса, содержащего статические методы, который используется в классе утилиты Collections.
Ответ 7
Реализация простой поддержки mixin/traits в java с использованием CGLib/javassit довольно проста. Вы можете посмотреть пример здесь для небольшого примера. Более полное, готовое к использованию решение может быть найдено: здесь
Ответ 8
С Java-8 добавлены методы интерфейса по умолчанию. Это, вместе с множественным наследованием интерфейсов в Java, должно позволить какой-то mixin. Очевидно, что интерфейсы должны работать независимо. Таким образом, будут значительные ограничения.