📚 Hub Books: Онлайн-чтение книгРазная литератураИнтернет-журнал "Домашняя лаборатория", 2007 №9 - Журнал «Домашняя лаборатория»

Интернет-журнал "Домашняя лаборатория", 2007 №9 - Журнал «Домашняя лаборатория»

Шрифт:

-
+

Интервал:

-
+
1 ... 351 352 353 354 355 356 357 358 359 ... 415
Перейти на страницу:
как color2. При объявлении без явной инициализации объект получает значение первой константы перечисления, так что color2 в момент объявления получает значение black;

• объекту можно присвоить значение, которое задается константой перечисления, уточненной именем перечисления, как для color1 и color2. Можно также задать значение базового типа, приведенное к типу перечисления, как для color3;

• нельзя сравнивать объекты разных перечислений, например color1 и color2, но можно сравнивать строки, возвращаемые методом Tostring, например color1.Tosting () и соlor2.ToString ();

• существуют явные взаимно обратные преобразования констант базового типа и констант перечисления;

• Метод Tostring, наследованный от класса Object, возвращает строку, задающую константу перечисления.

Персоны и профессии

Рассмотрим еще один пример работы с перечислениями, приближенный к реальности. Добавим в класс Person, рассмотренный в предыдущей лекции 16, поле, определяющее профессию персоны. Вполне разумно иметь перечисление, например, Profession, задающее список возможных профессий. Сделаем это поле, как обычно, закрытым, а доступ к нему обеспечим соответствующим свойством:

Profession prof;

public Profession Prof

{

    get {return (prof);}

    set {prof = value;}

}

Добавим еще в класс Person метод Analysis, анализирующий профессию, организуя традиционный разбор случаев и принимая решение на каждой ветви, в данном примере — выводя соответствующий текст:

public void Analysis()

{

    switch (prof)

        {

        case Profession.businessman:

           Console.WriteLine ("профессия: бизнесмен");

           break;

        case Profession.teacher:

           Console.WriteLine ("профессия: учитель");

           break;

        case Profession.engineer:

            Console.WriteLine ("профессия: инженер");

            break;

        default:

            Console.WriteLine ("профессия: неизвестна");

             break;

         }

}

Приведу простой тестирующий пример работы с объектом Person и его профессией:

public void TestProfession ()

{

      Person pers1 = new Person ("Петров");

      pers1.Prof = Profession.teacher;

      pers1.Analysis ();

}

Результаты работы с объектами перечислений, полученные при вызове тестов TestEnum и TestProfession, показаны на рис. 17.3.

Рис. 17.3. Результаты работы с перечислениями

18. Отношения между классами. Клиенты и наследники

Классы. Отношения между классами. Отношение клиенты — поставщики. Отношение наследования. Единичное наследование. Родители и наследники. Предки и потомки. Что наследуют потомки. Что могут изменить потомки. Одностороннее присваивание. Контроль типов и связывание — статическое и динамическое. Полиморфизм. Проектирование классов. Абстрактные классы. Классы поведения.

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

Каждый класс, как не раз отмечалось, играет две роли: он является модулем — архитектурной единицей, и он имеет содержательный смысл, определяя некоторый тип данных. Но классы программной системы — это ансамбль, в котором классы, играя свои роли, не являются независимыми — все они находятся в определенных отношениях друг с другом. Два основных типа отношений между классами определены в ОО-системах. Первое отношение "клиенты и поставщики", называется часто клиентским отношением или отношением вложенности (встраивания). Второе отношение "родители и наследники" называется отношением наследования.

Определение 1. Классы A и B находятся в отношении ''клиент-поставщик"; если одним из полей класса B является объект класса A. Класс A называется поставщиком класса в, класс B называется клиентом класса A.

Определение 2. Классы A и B находятся в отношении "родитель-наследник", если при объявлении класса B класс A указан в качестве родительского класса. Класс A называется родителем класса B, класс B называется наследником класса A.

Оба отношения — наследования и вложенности — являются транзитивными. Если B — клиент A и C — клиент B, то отсюда следует, что C — клиент A. Если B — наследник A и C — наследник B, то отсюда следует, что C — наследник A.

Определения 1 и 2 задают прямых или непосредственных клиентов и поставщиков, прямых родителей и наследников. Вследствие транзитивности необходимо ввести понятие уровня. Прямые клиенты и поставщики, прямые родители и наследники относятся к соответствующему уровню 1 (клиенты уровня 1, поставщики уровня 1 и так далее). Затем следует рекурсивное определение: прямой клиент клиента уровня к относится к уровню k+1.

Для отношения наследования используется терминология, заимствованная из естественного языка. Прямые классы-наследники часто называются сыновними или дочерними классами. Непрямые родители называются предками, а их непрямые наследники — потомками.

Замечу, что цепочки вложенности и наследования могут быть достаточно длинными. На практике вполне могут встречаться цепочки длины 10. Например, библиотечные классы, составляющие систему Microsoft Office, полностью построены на отношении вложенности. При программной работе с объектами Word можно начать с объекта, задающего приложение Word, и добраться до объекта, задающего отдельный символ в некотором слове некоторого предложения одного из открытых документов Word. Для выбора нужного объекта можно задать такую цепочку: приложение Word — коллекция документов — документ — область документа — коллекция абзацев — абзац — коллекция предложений — предложение — коллекция слов — слово — коллекция символов — символ. В этой цепочке каждому понятию соответствует класс библиотеки Microsoft Office, где каждая пара соседствующих классов связана отношением "поставщик-клиент".

Классы библиотеки FCL связаны как отношением вложенности, так и отношением наследования.

Длинные цепочки наследования достаточно характерны для классов этой библиотеки.

Отношения "является" и "имеет"

При проектировании классов часто возникает вопрос, какое же отношение между классами нужно построить. Рассмотрим совсем простой пример двух классов — Square и Rectangle, описывающих квадраты и прямоугольники. Наверное, понятно, что эти классы следует связать скорее отношением наследования, чем вложенности; менее понятным остается вопрос, а какой из этих двух классов следует сделать родительским. Еще один пример двух классов — Саr и Person, описывающих автомобиль и персону. Какими отношениями с этими классами должен быть связан класс Person_of_Саr, описывающий владельца машины? Может ли он быть наследником обоих классов? Найти правильные ответы на эти вопросы проектирования классов помогает понимание того, что отношение "клиент-поставщик" задает отношение "имеет" ("has"), а отношение наследования задает отношение "является" ("is а"). В случае классов Square и Rectangle понятно, что каждый объект квадрат "является" прямоугольником, поэтому между этими классами имеет место отношение наследования, и родительским классом является класс Rectangle, а класс Square является его потомком.

В случае автомобилей, персон и владельцев авто также понятно, что владелец "имеет" автомобиль и "является" персоной. Поэтому класс Person of Car является клиентом класса Саr и наследником класса Person.

Отношение вложенности

Рассмотрим два класса A и B, связанных отношением вложенности. Оба класса применяются для демонстрации идей и потому устроены просто, не неся особой смысловой нагрузки. Пусть класс-поставщик а уже построен. У класса два поля, конструктор, один статический и один динамический метод. Вот его текст:

1 ... 351 352 353 354 355 356 357 358 359 ... 415
Перейти на страницу:

Комментарии

Обратите внимание, что комментарий должен быть не короче 20 символов. Покажите уважение к себе и другим пользователям!

Никто еще не прокомментировал. Хотите быть первым, кто выскажется?