Тема 8. Производные классы. Полиморфизм



Производный класс можно рассматривать как расширение существующего класса (или наследника). Исходный класс называется базовым или родительским, а производный – подклассом или потомком. Производный класс представляет собой расширение или модификацию базового класса. Имея родительский класс, можно использовать единый интерфейс для получения нескольких производных классов.

Любой класс может быть родительским, и любой производный класс будет следовать его описанию. Класс-потомок может иметь дополнительные возможности по сравнению с базовым классом. В производном классе можно изменить права доступа, добавить новые элементы или перегрузить имеющиеся методы.

Синтаксис производного класса:

class ИмяПроизводногоКласса:(public/private/protected)

                   ИмяРодительскогоКласса {. . . };

Слова public, private и protected являются ключами доступа методов производного класса к элементам родительского класса. Ключ public не меняет тип доступа, ключ private делает для всех элементов базового класса тип доступа private, ключ protected разрешает доступ методов производного класса к общим элементам базового класса, но запрещает доступ для всех других методов. Если необходимо некоторым элементам изменить тип доступа, то их объявляю в производном классе повторно в соответствующей секции.

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

class A{. . .};

class B{. . .};

class C:public A, protected B{. . .};

Виртуальные функции

Функция–элемент может быть объявлена как virtual. В этом случае при ее вызове с указателем базового класса будет вызываться функция производного класса, если она переопределена.

Пример:

Class Base

{

public:

       virtual void virt(){cout<<”From Base, virt.”;}

       void nonVirt(){cout<<”From Base, non virt.”;}

};

class Derived:public Base

{

public:

       void virt(){cout<<”From Deriver, virt.”;}

       void nonVirt(){cout<<”From Derived, non virt.”;}

};

void main()

{

       Base *bp=new Derived;//Базовый указатель ссылается на произв.

       bp_>virt();//Вызов виртуальной ф-ции произв. класса.

       bp_>nonVirt();//Вызов невиртуальной ф-ции базового класса.

}

Виртуальный механизм можно обойти, если при вызове указать имя класса с операцией разрешения видимости:

       bp_>Base::virt();//Вызов виртуальной ф-ции произв. класса.

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

Виртуальная функция в базовом классе может быть определена как чистая. Для этого необходимо вместо кода этой функции написать “=0”. Класс, содержащий подобные функции называется абстрактным. Для такого класса невозможно создать представителя класса. Производный класс обязан содержать описание чистой функции.

Использование дружественных функций.

Функции, которые не являются членами класса, не имеют доступ к закрытым элементам класса. Доступ к ним можно разрешить, если объявить соответствующую функцию с помощью описателя friend:

class ClassA

{

       friend void ClassB::FuncName();

       friend void regularFunc(int);

       };

На дружественные функции не влияют спецификаторы доступа. Описания friend не взаимны. Дружественность не наследуется.

Практическое задание.

Вариант A.

Разработайте классы "Матрица" и "Вектор", определите набор основных операций между ними и методом фиктивных цветов изобразите график следующих поверхностей:

.

Здесь           — линейный оператор, действующий из  в ;
               — вектора в
                    — линейный оператор, сопряженный к ;
               — скалярное произведение между векторам  и  в эвклидовой метрике в :

Предусмотрите возможности сохранения матриц и векторов на диске и восстановления их из файла.

 

Вариант B.

Разработайте класс "Ломаная линия" и напишите программу, читающую с диска начальное и конечное положение линии и демонстрирующую последовательный переход линии из начального состояния в конечное.

Вариант C.

Разработайте классы "Матрица" и "Вектор", определите набор основных операций между ними и численно докажите следующие соотношения:

.

Результаты проиллюстрируйте графически.

Здесь                    — линейный оператор, действующий из  в ;
                               — линейный оператор, сопряженный к ;
                               — пространство значений оператора ;
                               — нуль‑пространство (ядро) оператора .

Значок обозначает ортогональное дополнение к заданному пространству. Предусмотрите возможности сохранения матриц и векторов на диске и восстановления их из файла.

 


Дата добавления: 2018-02-15; просмотров: 775; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!