Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSBasicCourse2ndedPodbelsky / CSBasicCourse2ndedPodbelsky.rtf
Скачиваний:
27
Добавлен:
22.03.2016
Размер:
11.9 Mб
Скачать

13.3. Наследование классов

Наиболее

богатым

в

отношении

повторного

использования

кода

и

полиморфизма является отношение наследования классов

"класс: наследование

классов" . Для него используют название "является" (is-a). При наследовании объект

производного класса служит частным случаем или специализацией объекта

базового класса. Например, велосипед является частным случаем транспортного

средства. Не проводя сравнительного анализа всех тонкостей возможных

отношений между классами (этим нужно заниматься в специальном курсе

,

посвященном объектно-ориентированной методологии, см., например, [3]), покажем

на примере рассматриваемых классов "точка на плоскости" и "окружность с

заданным точкой центром" как реализуется наследование в языке C#. Итак класс

Point будет базовым классом "класс: базовый класс" , а класс Circle сделаем его

наследником иначе говоря, производным "класс: производный базовый класс" от

него.

Для объявления класса, который является наследником некоторого базового

класса, используется следующий синтаксис:

модификаторыopt class имя_производного_класса

:имя_базового_класса

{операторы_тела_производного_класса}

Конструкция

: имя _ базового _ класса

в

стандарте

C#

называется

спецификацией базы класса "спецификация базы класса" .

Таким образом, класс Сircle как производный от базового класса Рoint можно

определить таким образом (программа 13_04.cs):

class Circle : Point // класс "окружность на плоскости"

{ // Закрытое поле:

double rad; // радиус окружности

// свойство для радиуса окружности:

public double Rad { get { return rad; }

set { rad = value; } }

// свойство для значения длины окружности:

public double Len { get { return 2 * rad * Math.PI; } }

// свойство для центра окружности:

public Point Centre

{

get

{

Point temp = new Point();

temp.X = X;

temp.Y = Y;

return temp;

}

set { X = value.X; Y = value.Y; }

}

public void display()

{

Console.WriteLine("Centre: X={0}, Y={1}; "

+

"Radius={2}, Length={3,6:f2}",

X, Y, rad, Len);

}

}

В производном классе Circle явно определены поле double rad, три уже

рассмотренных свойства Rad, Len Centre и метод display(). По сравнению с

предыдущими примерами класс Point не изменился. Он так же содержит два

закрытых поля, задающих координаты точки, и два открытых свойства X, Y,

обеспечивающие доступ к этим полям. В классе Point конструктор добавлен

компилятором. Нет явного определения конструктора и в классе Сircle. Поэтому

объекты класса Circle можно создавать только с умалчиваемыми значениями полей.

При наследовании производный класс "получает в наследство" все поля,

свойства и методы базового класса, за исключением конструктора – конструктор

базового класса

"конструктор: базового класса"

не наследуется. Получив от

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

"распорядиться с наследством". Поля базового класса

"поля базового класса"

непосредственно входят в число полей производного класса. Однако доступ к полям

базового класса для методов, свойств и объектов производного класса разрешен не

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

свойств и объектов производного класса.

Открытые поля, методы, и свойства базового класса доступны для методов,

свойств и объектов производного класса. В нашем примере класс Point имеет два

открытых свойства, которыми можно пользоваться как внутри класса Circle так и

во внешнем мире, обращаясь к этим свойствам с помощью объектов класса circle. В

методе display() производного класса выполняется непосредственное обращание к

унаследованным свойствам X, Y.

Особое внимание в нашем примере с наследованием нужно обратить на

свойство Circle.Centre. При агрегации и композиции класса Point в класс Circle

значением этого свойства служит ссылка на непосредственно существующи

й

объект класса Point. В случае наследования в объекте класса Circle объекта класса

Point нет – присутствуют только поля такого объекта и в классе Circle доступны

открытые свойства класса Point. Поэтому для объявления в классе Circle свойства

Centre объект класса Point приходится "реконструировать". В get-аксессоре явно

создаётся временный объект класса Point, его полям присваиваются значения полей,

унаследованных классом Circle от базового класса Point. Ссылка на этот временный

объект возвращается как значение свойства Circle.Centre. Set-аксессор свойства

Circle.Centre очень прост – используются унаследованные свойства X, Y класса

Point.

Следующий фрагмент программы (см. 13_04.cs) демонстрирует возможности

класса Сircle.

class Program

{

static void Main( )

{

Circle rim = new Circle( );

rim.X = 24;

rim.Y = 10;

rim.Rad = 2;

rim.display();

rim = new Circle( );

rim.display( );

}

}

В методе Main( ) создан объект класса Сircle. Он ассоциирован со ссылкой

rim, и с ее помощью осуществляется доступ как к свойствам и методам объекта

класса Сircle, так и к свойствам объекта базового класса Рoint. Следующие

результаты выполнения программы дополняют приведенные объяснения:

Centre: X=24, Y=10; Radius=2, Length= 12,57

Centre: X=0, Y=0; Radius=0, Length= 0,00

В языке UML предусмотрено специальное обозначение для отношения

наследования классов "класс: отношения наследования классов" . Два класса (см.

рис. 13.3) изображаются на диаграмме отдельными прямоугольниками, которые

соединены сплошной линией со стрелкой на одном конце. Стрелка направлена на

базовый класс.

Рис. 13.4 . Диаграмма к программе 13_04.cs с наследованием классов

Соседние файлы в папке CSBasicCourse2ndedPodbelsky