Добавить в цитаты Настройки чтения

Страница 310 из 371



Приведу примеры объявлений классов-перечислений:

public enum Profession{teacher, engineer, businessman};

public enum MyColors {red, blue, yellow, black, white};

public enum TwoColors {black, white};

public enum Rainbow {красный, оранжевый, желтый, зеленый, голубой, синий, фиолетовый};

public enum Sex: byte {man=1, woman};

public enum Days: long {Sun,Mon,Tue,Wed,Thu, Fri, Sat};

Вот несколько моментов, на которые следует обратить внимание при объявлении перечислений:

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

• константы разных перечислений могут совпадать, как в перечислениях MyColors и TwoColors. Имя константы всегда уточняется именем перечисления-,

• константы могут задаваться словами русского языка, как в перечислении Rainbow;

• разрешается задавать базовый класс перечисления. Для перечисления Days базовым классом задан класс long;

• разрешается задавать не только базовый класс, но и указывать начальный элемент подмножества, на которое проецируется множество значений перечисления. Для перечисления Sex в качестве базового класса выбран класс byte, а подмножество значений начинается с 1, так что хранимым значением константы man является 1, a woman — 2.

Рассмотрим теперь пример работы с объектами — экземплярами различных перечислений:

public void TestEnum()

{

    //MyColors colorl = new MyColors(MyColors.blue);

    MyColors colorl= MyColors.white;

    TwoColors color2;

    color2 = TwoColors.white;

    //if (color1!= color2) color2 = color1;

    if(color1.ToString ()!= color2.ToString())

          Console.WriteLine ("Цвета разные: {0}, {1}",

            color1, color2);

     else Console.WriteLine("Цвета одинаковые: {0},

            {1}",color1, color2);

     Rainbow color3; color3 = (Rainbow)3;

     if (color3!= Rainbow.красный)color3 =Rainbow.красный;

     int num = (int)color3;

     Sex who = Sex.man;

     Days first_work_day = (Days) (long)l;

     Console.WriteLine ("color1={0}, color2={1},

            color3={2}",color1, color2, color3);

     Console.WriteLine ("who={0}, first_work_day={1}",

            who,first_work_day);

}

Данный пример иллюстрирует следующие особенности работы с объектами перечислений-.

• объекты перечислений нельзя создавать в объектном стиле с использованием операции new, поскольку перечисления не имеют конструкторов;

• объекты можно объявлять с явной инициализацией, как color1, или с отложенной инициализацией, как 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.