Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

Наследование



Наследование — один из трех фундаментальных принципов объектно-ориентиро­ванного программирования, поскольку именно благодаря ему возможно созда­ние иерархических классификаций. Используя наследование, можно создать общий класс, который определяет характеристики, присущие множеству связанных элемен­тов. Этот класс затем может быть унаследован другими, узкоспециализированными классами с добавлением в каждый из них своих, уникальных особенностей.

В языке С# класс, который наследуется, называется базовым. Класс, который на­следует базовый класс, называется производным. Следовательно, производный класс — это специализированная версия базового класса. В производный класс, наследующий все переменные, методы, свойства, операторы и индексаторы, определенные в базо­вом классе, могут быть добавлены уникальные элементы.

С# поддерживает наследование, позволяя в объявление класса встраивать другой класс. Это реализуется посредством задания базового класса при объявлении произ­водного. Лучше всего начать с примера. Рассмотрим класс TwoDShape, в котором оп­ределяются атрибуты "обобщенной" двумерной геометрической фигуры {например, квадрата, прямоугольника, треугольника и т.д.).

// Класс двумерных объектов, class TwoDShape {

public double width;

public double height;

public void showDiraO {

Console.WriteLine("Ширина и высота равны " + width + " и " + height);

)

}

Класс TwoDShape можно использовать в качестве базового (т.е. как стартовую площадку) для классов, которые описывают специфические типы двумерных объек­тов. Например, в следующей программе класс TwoDShape используется для выведения класса Triangle. Обратите внимание на то, как объявляется класс Triangle. // Простая иерархия классов.

using System;

// Класс двумерных объектов. class TwoDShape {

public double width;

public double height;

public void showDimO {

Console.WriteLine("Ширина и высота равны " + width + " и " + height);

>

)

II Класс Triangle выводится из класса TwoDShape. class Triangle: TwoDShape \

public string style; // Тип треугольника.

// Метод возвращает площадь треугольника, public double area() {

return width * height / 2;

}

// Отображаем тип треугольника, public void showStyleO {

Console.WriteLine("Треугольник " + style);

>

}

class Shapes {

public static void Main() (Triangle tl - new Triangle(); Triangle t2 = new Triangle();

tl.width = 4.0;

tl.height = 4.0;

tl.style = "равнобедренный";

t2.width = 8.0;

t2.height - 12.0;

t2.style - "прямоугольный";

Console.WriteLine("Информация о tl: "); tl.showStyleO; tl.showDimt);

Console.WriteLine("Площадь равна " + tl.area{)); Console.WriteLine();

Console.WriteLine("Информация о t2: "); 12.showStyleO; t2.showDira();

Console.WriteLine("Площадь равна " + t2.area());

)

}

Вот результаты работы этой программы. Информация о t1: Треугольник равнобедренный Ширина и высота равны 4 и 4 Площадь равна 8

Информация о t2: Треугольник прямоугольный Ширина и высота равны 8 и 12 Площадь равна 48

В классе Triangle создается специфический тип объекта класса TwoDShape, в данном случае треугольник. Класс Triangle содержит все элементы класса TwoDShape и, кроме того, поле style, метод area () и метод showStyle О. В пере­менной style хранится описание типа треугольника, метод area о вычисляет и воз­вращает его площадь, а метод showStyle () отображает данные о типе треугольника.

Ниже приведен синтаксис, который используется в объявлении класса Triangle, чтобы сделать его производным от класса TwoDShape. | class Triangle: TwoDShape {Этот синтаксис можно обобщить. Если один класс наследует другой, то имя базо­вого класса указывается после имени производного, причем имена классов разделяют­ся двоеточием. В С# синтаксис наследования класса очень прост для запоминания и использования.

Поскольку класс Triangle включает все члены базового класса, TwoDShape, он может обращаться к членам width и height внутри метода агеа(). Кроме того, внутри метода Main () объекты tl и t2 могут прямо ссылаться на члены width и height, как если бы они были частью класса Triangle. Несмотря на то что класс TwoDShape является базовым для класса Triangle, это совершенно независимый и автономный класс. То, что его использует в качестве ба­зового производный класс (классы), не означает невозможность использования его самого. Например, следующий фрагмент кода абсолютно легален:

TwoDShape shape = new TwoDShape();

shape.width = 10; shape.height = 20;

shape.showDim();

Безусловно, объект класса TwoDShape "ничего не знает" и не имеет права доступа К классу, производному от TwoDShape.

Общая форма объявления класса, который наследует базовый класс, имеет такой вид:

class имя_производного_класса: имя_базо&ого_класса { // тело класса

}

Для создаваемого производного класса можно указать только один базовый класс. В С# (в отличие от С++) не поддерживается наследование нескольких базовых клас­сов в одном производном классе. Этот факт необходимо учитывать при переводе С++-кода на С#. Однако можно создать иерархию наследования, в которой один производный класс становится базовым для другого производного класса. И конечно же, ни один класс не может быть базовым (ни прямо, ни косвенно) для самого себя.

Основное достоинство наследования состоит в том, что, создав базовый класс, ко­торый определяет общие атрибуты для множества объектов, его можно использовать для создания любого числа более специализированных производных классов. В каж­дом производном классе можно затем точно "настроить" собственную классифика­цию. Вот, например, как из базового класса TwoDShape можно вывести производный класс, который инкапсулирует прямоугольники:

// Класс прямоугольников Rectangle, производный //от класса TwoDShape. class Rectangle: TwoDShape {

// Метод возвращает значение true, если // прямоугольник является квадратом, public bool isSquare О {

if(width == height) return true; return false;

)

II Метод возвращает значение площади прямоугольника, public double area О (return width * height;

)

}

Класс Rectangle включает класс TwoDShape и добавляет метод isSquareO, ко­торый определяет, является ли прямоугольник квадратом, и метод агеа(), вычис­ляющий площадь прямоугольника.


Полиморфизм.

Полиморфизм (от греческого слова polymorphism, означающего "много форм") — это качество, которое позволяет одному интерфейсу получать доступ к целому классу дейст­вий. Простым примером полиморфизма может послужить руль автомобиля. Руль (интерфейс) остается рулем независимо от того, какой тип рулевого механизма исполь­зуется в автомобиле. Другими словами, руль работает одинаково в любом случае: осна­щен ли ваш автомобиль рулевым управлением прямого действия, рулевым управлением с усилителем или реечным управлением. Таким образом, поворот руля влево заставит автомобиль поехать влево независимо от типа используемого в нем рулевого управле­ния. Достоинство такого единообразного интерфейса состоит, безусловно, в том, что, если вы знаете, как обращаться с рулем, вы сможете водить автомобиль любого типа.

Тот же принцип можно применить и к программированию. Рассмотрим, напри­мер, стек (stack), т.е. область памяти, функционирующую по принципу "последним пришел — первым обслужен". Предположим, вы пишете программу, для которой нужно организовать три различных типа стека. Один стек предназначен для целочис­ленных значений, второй — для значений с плавающей точкой, а третий — для сим­волов. В этом случае для реализации каждого стека используется один и тот же алго­ритм, несмотря на различие в типах сохраняемых данных. В случае не объектно-ориентированного языка вам пришлось бы создать три набора "стековых" подпро­грамм, имеющих различные имена. Но благодаря полиморфизму в среде С# можно создать один общий набор "стековых" подпрограмм, который обрабатывает все три типа стека. Иными словами, зная, как использовать один стек, можно использовать все остальные.

Концепцию полиморфизма часто выражают такой фразой: "один интерфейс — много методов". Это означает, что для выполнения группы подобных действий можно разработать общий интерфейс. Полиморфизм позволяет понизить степень сложности программы, предоставляя программисту возможность использовать один и тот же ин­терфейс для задания общего класса действий. Конкретное (нужное в том или ином случае) действие (метод) выбирается компилятором. Программисту нет необходимо­сти делать это вручную. Его задача — правильно использовать общий интерфейс.





Дата публикования: 2014-11-18; Прочитано: 277 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.007 с)...