Не обнаружил проекты, которые используются в примерах в лекции, также не увидел список задач. |
Отношения между классами. Клиенты и наследники
Расширение определения клиента класса
До сих пор мы говорили, что клиент содержит поле, представляющее объект класса поставщика. Это частая, но не единственная ситуация, когда класс является клиентом другого класса. Возможна ситуация, когда метод клиентского класса локально создает объект поставщика, вызывает его методы в собственных целях, но по завершении метода локальный объект заканчивает свою жизнь. Еще одна возможная ситуация - когда объекты поставщика вообще не создаются ни конструктором, ни методами класса клиента, но клиент вызывает статические методы класса поставщика. Оба эти варианта демонстрируют следующие два метода класса B:
public void MethodB2() { ClassA loc = new ClassA("локальный объект А",77); loc.MethodA(); } public void MethodB3() { ClassA.StatMethodA(); }
Дадим теперь расширенное определение клиента.
Определение 3. Класс B называется клиентом класса A, если в классе B создаются объекты класса A - поля или локальные переменные - или вызываются статические поля или методы класса A.
Отношения между клиентами и поставщиками
Что могут делать клиенты и что могут делать поставщики? Класс-поставщик создает свойства (поля) и сервисы (методы), предоставляемые своим клиентам. Клиенты создают объекты поставщика. Вызывая доступные им методы и поля объектов, они управляют работой созданных объектов поставщика. Клиенты не могут ни повлиять на поведение методов поставщика, ни изменить состав предоставляемых им полей и методов, они не могут вызывать закрытые поставщиком поля и методы класса.
Класс-поставщик интересен клиентам своей открытой частью, составляющей интерфейс класса. Но большая часть класса может быть закрыта для клиентов - им незачем вникать в детали представления и в детали реализации. Сокрытие информации вовсе не означает, что разработчики класса не должны быть знакомы с тем, как все реализовано, хотя иногда и такая цель преследуется. В общем случае сокрытие означает, что классы-клиенты строят свою реализацию, основываясь только на интерфейсной части класса-поставщика. Поставщик закрывает поля и часть методов класса от клиентов, задавая для них атрибут доступа private или protected. Он может некоторые классы считать привилегированными, предоставляя им методы и поля, недоступные другим классам. В этом случае поля и методы, предназначенные для таких vip-персон, снабжаются атрибутом доступа internal, а классы с привилегиями должны принадлежать одной сборке.
В заключение построим тест, проверяющий работу с объектами классов A и B:
public void TestClientSupplier() { ClassB objB = new ClassB("AA",22, "BB",33); objB.MethodB1(); objB.MethodB2(); objB.MethodB3(); }
Результаты работы этого теста показаны на рис. 18.1.
Сам себе клиент
Зададимся вопросом, может ли класс быть сам себе клиентом, другими словами, может ли поле класса быть объектом описываемого класса? Другой, не менее интересный вопрос - могут ли два класса быть одновременно клиентами и поставщиками друг для друга? Ответы на оба вопросы положительны, и подобные ситуации типичны и не являются какой-либо экзотикой.
Первая ситуация характерна для динамических структур данных. Элемент односвязного списка имеет поле, представляющее элемент односвязного списка; элемент двусвязного списка имеет два таких поля; узел двоичного дерева имеет два поля, представляющих узлы двоичного дерева. Эта ситуация характерна не только для рекурсивно определяемых структур данных. Вот еще один типичный пример. В классе Person могут быть заданы два поля - Father и Mother, задающие родителей персоны, и массив Children. Понятно, что все эти объекты могут быть того же класса Person.
Не менее часто встречается ситуация, когда классы имеют поля, взаимно ссылающиеся друг на друга. Типичным примером могут служить классы Man и Woman, первый из которых имеет поле wife класса Woman, а второй - поле husband класса Man.
Заметьте, классы устроены довольно просто - их тексты понятны, отношения между классами очевидны. А вот динамический мир объектов этих классов может быть довольно сложным, отношения между объектами могут быть запутанными; для объектов характерны не только любовные треугольники, но и куда более сложные фигуры.