Отношения между классами (объектами)

По моей практике преподавания вопрос отношений между классами (или объектами) почему-то вызывает проблемы. Из-за чего так происходит, не могу сказать. Когда я изучал ООП, мне это показалось настолько очевидным, что не стоило даже упоминания — вся логика ООП не просто кричит, она вопиет об очевидности таких отношений и правилах их построения. Но тем не менее этот вопрос часто требует объяснений. Чем мы сейчас и займемся, прежде чем продолжим изучение новых конструкций языка Java.

Теоия ООП выделяет три основных отношения между классами:

  1. Ассоциация
  2. Агрегация и композиция
  3. Обобщение/Расширение (наследование)

Последний пункт мы с вами уже рассматривали, так что сосредоточимся на первых двух.

 

Ассоциация

Ассоциация означает, что объекты двух классов могут ссылаться один на другой, иметь некоторую связь между друг другом. Например Менеджер может выписать Счет. Соответственно возникает ассоциация между Менеджером и Счетом. Еще пример — Преподаватель и Студент — т.е. какой-то Студент учится у какого-то Преподавателя. Ассоциация и есть описание связи между двумя объектами. Студент учится у Преподавателя. Идея достаточно простая — два объекта могут быть связаны между собой и это надо как-то описать.

Агрегация и композиция

Агрегация и композиция на самом деле являются частными случаями ассоциации. Это более конкретизированные отношения между объектами.
Агрегация — отношение когда один объект является частью другого. Например Студент входит в Группу любителей физики.
Композиция — еще более «жесткое отношение, когда объект не только является частью другого объекта, но и вообще не может принадлежат еще кому-то. Например Машина и Двигатель. Хотя двигатель может быть и без машины, но он вряд ли сможет быть в двух или трех машинах одновременно. В отличии от студента, который может входить и в другие группы тоже. Такие описания всегда несколько условны, но тем не менее.

Техническая реализация

На самом деле каких-либо сложных и высокоумных технических решений нет — все достаточно тривиально. В одном классе делается ссылка на другой и наоборот (не всегда). Дальше идет развитие данной идеи в зависимости например от количества связей. В машине четыре колеса и она имеет связь со всеми — значит в машине будет ссылка на список колес (или массив). Давайте соединим нашего робота с оператором, который им управляет. Между ними можно установить ассоциацию через ссылки в одном классе на другой класс. Т.е. класс Robot имеет ссылку на класс Operator и наоборот — класс Operator имеет ссылку на класс Robot.

Класс Robot

Класс Operator

Чего-то другого человечество пока не придумало. Как я уже упоминал, можно несколько разнообразить виды ссылок, но идея останется прежней. Можно делать ссылки только в одном классе — тогда связь будет односторонняя, может быть несколько ссылок или ссылка на список (массив). Но все равно сказать одному классу, что он связан с другим можно только по такому принципу.
Кстати, когда мы размещали наши компоненты с овалом, прямоугольником на форме, то тут можно говорить о композиции — форма содержит внутри себя список компонентов класса JComponent для хранения всех компонентов, которые ей передают.

Еще один способ взаимодействия объектов

Эта ситуация возникает тогда, когда постоянной связи между объектами не предусматривается вообще, но какие-то данные надо передать от одного другому. Можно воспользоваться вариантом передачи объекта прямо в методе. Например, наш робот может иметь метод, который принимает данные из другого робота — его координаты — для того, чтобы туда переместиться. Значит надо сделать метод, который в качестве параметра будет иметь объект класса Robot.
Как видите все достаточно банально и просто. Мы очень скоро столкнемся с этими понятиями при рассмотрении примеров.

10 comments to Отношения между классами

  • Алекс  says:

    Здравствуйте, спасибо за интересный сайт. Могли бы вы подробнее прокомментировать строку 9 класса Robot

    private Operator operator;

    и строки 5-8 класса Oprerator

    private String firstName;
    private String lastName;
    // Оператор управляет конкретным роботом
    private Robot robot;

    — т.е. что это за конструкция? Это и не создание нового объекта, и не конструктор. Похоже только на создание ссылки на объект, но могли бы вы объяснить как это работает?

    Также похожие конструкции есть в следующей статье
    private Object object;
    private ObjectBox next;
    Заранее благодарен.

  • Алекс  says:

    Извините за поспешный вопрос. Насколько я правильно разобрался, это просто поля класса, ссылки на потенциальные (еще не существующие) объекты. Их следует объявить для последующего прописывания методов данного класса (эти поля используются в качестве атрибутов метода).

  • Юрий  says:

    Вот эта вот глава совсем непонятная.

    // Робот управляется оператором
    private Operator operator;
    // Оператор управляет конкретным роботом
    private Robot robot;

    абсолютно одинаковые команды, почему робот УПРАВЛЯЕТСЯ, а оператор УПРАВЛЯЕТ? Почему не наоборот?
    Вообще не понял этих примеров.

    Вот этот блок что делает?
    public Operator(String firstName, String lastName) {
    this.firstName = firstName;
    this.lastName = lastName;

    // У оператора можно спросить каким роботом он управляет
    public Robot getRobot() {
    return robot;
    каким образом мы у него спрашиваем? Запускаем программу ничего не меняется.

    Как настроить свой мозг на понимание всего вот этого?

    • admin  says:

      А в жизни как должно быть ? Робот будет управлять оператором или все-таки оператор в ответе за робота и именно он посылает ему команды ?
      Но для того, чтобы посылать команды надо иметь СВЯЗЬ с роботом. А как это сделать не имея АССОЦИАЦИИ — связи между объектами ? Связь может быть в виде ссылки на нужный объект. А вот какую мысль Вы вкладываете в эту связь — это уже определяется требованиями к задаче.
      Ваши вопросы говорят о том, что ООП для Вас пока очень слабо понятная область — дерзайте дальше 🙂

      По поводу «настроить голову» — читать, пробовать, ошибаться, задавать вопросы и искать ответы. Книги, форумы, статьи, примеры.
      Если хотите это делать с большей эффективностью — занимайтесь с хорошим тренером/преподавателем.

  • Andrey  says:

    Не совсем понимаю, в примере с роботом и оператором, это композиция или агрегация? Ведь жизненный цикл поля «private Robot robot» в классе «Operator» ограничен самим классом «Operator» и при разрушении объекта класса «Operator» поле «private Robot robot» тоже разрушается?

    • admin  says:

      На мой взгляд это больше агрегация — хотя здесь много субъективного.
      Что касается «разрушения» — это же просто ссылка на существующий объект. У робота есть ссылка на оператора. Если надо «отключить» оператора от робота, то надо эту ссылку обнулить.
      При учете «сборщика мусора» объект в Java не уничтожается до тех пор, пока на него есть ссылки. Если таких ссылок нет — объект будет утилизирован.

  • Formfaktor  says:

    Здравствуйте.
    Агрегация — это Робот и Оператор.
    Композиция — это Робот и, например, Батарея питания.
    Т.е. при агрегации передаётся ссылка на уже созданный объект (через метод или конструктор)? А при композиции — ссылка на объект инициализируется при описании класса (в конструкторе или сразу при объявлении переменной экземпляра )?
    Я правильно понял?

    • admin  says:

      В общем — правильно. И про конструктор тоже в принципе верное замечание. Хотя такое не всегда делается через конструктор — тут грань достаточно тонкая.

      • Formfaktor  says:

        Спасибо большое. Мня тема отношений между классами тяжеловато даётся. Многие авторы ее по разному описывают ((. И это сбивает с толку.

        • admin  says:

          Здесь важно видеть, что объекты между собой могут иметь связь. Какую — это уже можно пытаться классифицировать, но немало зависит от контекста.
          Например, когда автобус едет по шоссе — связь водитель-автобус весьма жесткая. А когда автобус стоит в парке или на ремонте, то водителя там нет и он в общем не нужен. Поэтому каждый раз надо думать о задаче, а связи между объектами — это уже вторично.

Leave a reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Лимит времени истёк. Пожалуйста, перезагрузите CAPTCHA.