2013-09-22 1 views
0

Скажет, у меня есть следующий класс:Композиция в Java

public class BodyClass{ 

private LegClass myLeftLeg; 
private LegClass myRightLeg; 
private NoseClass myNose; 

... 

} 

позже где-то глубоко в программе, я собираюсь иметь уединенный экземпляр myRightLeg.

Теперь, почему я не знаю легко (или вообще), к какому объекту BodyClass относится этот rightleg, не говоря уже о том, в какой класс этой переменной содержится этот экземпляр? Почему в составных отношениях информация о родительском классе не сохраняется автоматически в дочерних объектах во время выполнения?

Не может быть мира, в котором Java lazily-загружает каждую переменную класса с информацией о самом родительском классе?

Зачем это плохо? И разве это не будет достаточно солидным преимуществом?

Я слышал, как люди говорят, что такие вещи, как подклассы, ничего не знают о своих суперклассах, а переменные экземпляра не должны ничего знать о своих родительских классах, но, честно говоря, я не понимаю, почему нет.

Моего вопрос относится к этому вопросу:

How do you find all subclasses of a given class in Java?

+1

Вы всегда можете проверить тип экземпляра, используя operatorOf operator –

+0

Какая проблема при работе с? Это пахнет как проблема [XY] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). –

+0

привет Мэтт, я использую DB4o, и в этом проблема возникает. Если у меня есть объект Model, и я могу вызвать store() для этого объекта, этот объект Model может иметь другой объект Model как переменную экземпляра. Это очень распространено, особенно в моделях классов моделей для таблиц реляционных баз данных. Но если я вызову store() в объекте переменной экземпляра, как DB4o знает, что этот экземпляр-переменный объект был дочерним по отношению к родительскому объекту модели? Я не уверен, что это так, и должно. –

ответ

1

Теперь, как же я не знаю, легко (или вообще), какой объект BodyClass это rightleg относится к, не говоря уже о каком классе это переменная экземпляра содержится в?
...
Почему в композиционных отношениях информация о родительском классе не сохраняется автоматически в дочерних объектах во время выполнения?

Потому что the language specification не включает это требование.

В Java объекты не содержат ссылок на другие объекты, если они явно не заданы им как поля или неявно заданы в виде унаследованных полей. Вот и все. Если вы хотите, чтобы ваши объекты, чтобы узнать, какие объекты знают о них, вы должны запрограммировать сами:

class LegClass { 
    private BodyClass body; 

    void setBody(BodyClass body) { 
     this.body = body; 
    } 
} 

class BodyClass { 
    // snip... 
    void setRightLeg(LegClass rightLeg) { 
     this.myRightLeg = rightLeg; 
     rightLeg.setBody(this); 
    } 
} 

Обратите внимание на tight coupling это вводит между этими двумя классами. Tight coupling is generally not a good thing.

Я не понимаю, почему это особенно полезно, и такая «особенность» сворачивает в сторону нарушения некоторых из принципов объектно-ориентированного программирования (который исповедует Java), такие как Encapsulation и Single Responsibility. Поле, которое знает о каком экземпляре (-ах) (помните, что нет причин, чтобы он был только одним!) Ссылка, как правило, является запахом кода.

+0

Его delibrate на java-части, чтобы реализовать его так. Если класс memebr varibale знает, к какому экземпляру он принадлежит, это приведет к очень плотной связи. Одной из основных причин использования композиции является свободное сцепление. – Lokesh

+0

ребята, кроме проблем с производительностью, я не вижу абсолютно никакой причины, почему не должно быть автоматической информации о взаимосвязи между переменными экземпляра и их родительскими классами. Это поможет во многих обстоятельствах. Раньше я сталкивался с этой проблемой. Обычно для решения проблемы я использую статическую переменную экземпляра hashtable в родительском классе. –

+0

посмотреть эту проблему: http://stackoverflow.com/questions/492184/how-do-you-find-all-subclasses-of-a-given-class-in-java –

0

средство композиция имеет Наследование означает ЯВЛЯЕТСЯ

Пример: Автомобиль имеет двигатель и автомобиль является автомобильный

В программировании это представлено как:

класса Engine {} // двигатель класс.

класс Автомобиль {} // Автомобильный класс, который является родителем класса Car.

// Автомобиль - это автомобиль, поэтому класс автомобиля расширяет класс автомобилей. класс Автомобиль расширяет Автомобиль {

// У автомобиля есть Двигатель, поэтому в классе автомобилей есть экземпляр класса Двигатель в качестве его члена. частный Двигатель; }

1

Много причин, но я думаю, что я бы сократить его до 2-х больших из них:

1) В отличие от реальных объектов, Java объекты могут быть более чем в одном месте. Вы не обязательно будете называть это «композиционными отношениями», но «составные отношения» - это не то, что существует на Java. В Java у вас есть поля, содержащие ссылки на другие объекты, и более чем одно поле в нескольких местах может указывать на один и тот же целевой объект. Поэтому во многих случаях не имеет смысла даже спрашивать о «владельце» или «контейнере»

2) Вы можете организовать такие обратные ссылки самостоятельно, но обычно это плохая идея. Класс Leg - это место, где вы помещаете код, который касается ноги. Этот код решает проблемы с ногами и не должен вообще заботиться о том, есть ли вокруг тело. Если у вас есть проблемы с целым телом, которые могут быть решены только в том случае, если вы знаете о теле и ноге, а затем решайте их в классе тела. Это называется «разделение проблем», и это основной способ организовать программное обеспечение, чтобы мы могли его понять.