Составление нескольких классов Java и сокращение стандартных шаблонов

Все мы знаем, почему в Java не должно быть множественного наследования. Так что это не вопрос о том, что уже обсуждалось до коровы.

Здесь обсуждается, что мы будем делать, если захотим создать класс, обладающий характеристиками двух или более других классов.

Вероятно, большинство из нас сделали бы это, чтобы «наследовать» от трех классов. Для простоты я пропустил конструктор.:

class Car
extends Vehicle
{
  final public Transport transport;
  final public Machine machine;
}

Таким образом, класс Car напрямую наследует методы и объекты класса Vehicle, но должен явно ссылаться на транспорт и машину, чтобы ссылаться на объекты, созданные в классах Transport и Machine.

Car car = new Car();
car.drive(); // from Vehicle
car.transport.isAmphibious(); // from Transport
car.machine.getCO2Footprint(); // from Machine

Я думал, что это хорошая идея, пока не столкнулся с фреймворками, требующими методов установки и получения. Например, XML

<Car amphibious='false' footPrint='1000' model='Fordstatic999'/>

будет искать методы setAmphibious(..), setFootPrint(..) и setModel(..). Поэтому мне приходится проецировать методы из классов Transport и Machine

class Car
extends Vehicle
{
  final public Transport transport;
  final public Machine machine;
  public void setAmphibious(boolean b){
    this.transport.setAmphibious(b);
  }
  public void setFootPrint(String fp){
    this.machine.setFootPrint(fp);
  }
}

Это нормально, если бы было всего несколько характеристик. Прямо сейчас я пытаюсь адаптировать весь SmartGWT в GWT UIBinder, особенно те классы, которые не являются виджетами GWT. Есть много характеристик для проекта.

Было бы неплохо, если бы существовала какая-то форма структуры аннотаций, подобная этой:

class Car
extends Vehicle
@projects {Transport @projects{Machine @projects Guzzler}}
{
  /* No need to explicitly instantiate Transport, Machine or Guzzler */
  ....
}

Там, где, в случае существования общих имен характеристик, характеристики Машины будут иметь приоритет над Обжорами, а Транспорт будет иметь приоритет над Машинами, а Транспортные средства будут иметь приоритет над Транспортными. Затем инфраструктура аннотаций создаст экземпляры Transport, Machine и Guzzler как скрытые элементы Car и расширится, чтобы разбить защищенные/общедоступные характеристики в соответствии с приоритетом, определяемым последовательностью аннотаций @project, в фактический исходный код или в байт-код. Желательно в байт-код. Так что метод setFootPrint можно найти как в Machine, так и в Guzzler, будет проецироваться только метод Machine.

Вопросы:

  1. Вам не кажется хорошей идеей иметь такую ​​структуру?
  2. Такая структура уже существует? Подскажите где/что.
  3. Есть ли плагин eclipse, который это делает?
  4. Есть ли где-нибудь предложение или план, который вы знаете о такой структуре аннотаций?

Также было бы замечательно, если бы структура аннотаций/плагинов позволяла мне указать, что логическое значение, целое число или что-то еще нужно преобразовать из строки, и также выполняла преобразование/анализ для меня.

Посоветуйте, кто-нибудь. Надеюсь, формулировка моего вопроса была достаточно ясной. Спасибо.

Отредактировано: чтобы энтузиасты ОО не делали поспешных выводов, я переименовал название этого вопроса.


person Blessed Geek    schedule 18.02.2010    source источник
comment
Не совсем вопрос, а попытка начать дискуссию. Рассматривая это как вопрос, я отвечаю: 1) Нет, 2) Насколько я знаю, нет, 3) Насколько мне известно, нет, 4) Насколько мне известно, нет.   -  person Stephen C    schedule 18.02.2010
comment
Я бы не стал расширять один из классов, а затем использовать композицию для других. Если вам нужен полиморфизм, создайте три интерфейса и реализуйте три из них, возьмите класс Vehicle, сделайте его абстрактным (или нет) транспортным средством и используйте композицию, чтобы получить доступ к его методам. Почему для наследования вы выбрали Транспортное средство, а не Машину или Транспорт? Только так вы не сможете сделать это List‹Machine› list = new ArrayList‹Machine›(); list.add(новый автомобиль())   -  person Lombo    schedule 18.02.2010
comment
Я бы подумал, что потребность в такой структуре — это плохой дизайн класса. Может быть, вы неправильно используете фреймворк, который хотите адаптировать? Попробуйте использовать больше интерфейсов :)   -  person Janusz    schedule 18.02.2010
comment
Я думаю, что энтузиасты объектно-ориентированного дизайна, включая меня, обычно делают поспешные выводы, читая вопрос о множественном наследовании, и голосуют против него. Пожалуйста, внимательно прочитайте мой вопрос и подробно ответ, опубликованный Божо. Речь идет о составлении характеристик нескольких классов и ничего о представлении интерфейсов. Может быть, я неправильно сформулировал заголовок и должен был пропустить провоцирующее множественное наследование и озаглавить компонент компоновки класса вопросов.   -  person Blessed Geek    schedule 18.02.2010
comment
Ваш вопрос имеет смысл. Я также сталкиваюсь с такими проблемами в дикой природе, и Java не особенно хорошо приспособлен для их решения.   -  person Jordão    schedule 24.05.2010
comment
@BlessedGeek Я знаю, что это старый пост, но я использую AspectJ уже почти 2 года, и его невероятное сокращение шаблонов. ИМХО лучше примеров Божо.   -  person Adam Gent    schedule 09.09.2012


Ответы (3)


Возможно, это не совсем то, что вы ищете, но вы можете взглянуть на Mixins:

person Bozho    schedule 18.02.2010
comment
Интересный материал, но ИМО может раздражать. Что касается примесей, стоит упомянуть Groovy, который (как вы знаете) представляет собой надмножество Java с примесями (groovy .codehaus.org/Runtime+mixins) - person Dan Rosenstark; 24.05.2010

Если у вас есть некоторая свобода в вашей среде, обязательно взгляните на Scala. У него есть особенности, которые позволят вам решить эту проблему. Трейты являются композиционными (pdf) и предлагают гораздо лучшую стратегию повторного использования кода. чем наследование.

Вернувшись на землю Java, вы можете использовать AspectJ объявления Inter-Type для достижения чего-то похожие (примеси). Для него также есть очень хороший подключаемый модуль Eclipse: AJDT.

person Jordão    schedule 23.05.2010

Некоторые фреймворки (по крайней мере, Spring) поддерживают указание пути для сеттеров и геттеров. Таким образом, сеттер будет больше похож на

<property name="transport.amphibious" value="true" />

Вы должны посмотреть, сможете ли вы использовать такие опции.

person Robin    schedule 18.02.2010
comment
Я специально работаю над адаптацией SmartGWT к UIBinder прямо сейчас, и то, что вы рекомендуете, невозможно выполнить в UIBinder. - person Blessed Geek; 18.02.2010