Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Закрытое (private) наследование ⇐ ПредыдущаяСтр 7 из 7
Закрытые члены базового класса недоступны напрямую с использованием дополнительных методов класса-наследника (при любом способе наследования). Работа внутри класса-наследника с такими получаемыми закрытыми членами базового класса возможна только с использованием открытых и защищенных методов базового класса.
Закрытые и защищенные получаемые методы недоступны для манипули-рования с объектом вне класса. Они могут использоваться как подпрограммы другими методами класса.
При закрытом наследовании открытые и защищенные члены базового класса (любые) доступны только внутри производного класса и недоступны извне (через объекты производного класса), как и его собственные закрытые члены. Таким образом, приведенная таблица показывает вид доступа для членов в типе наследнике для типа наследника следующего уровня. Но, для текущего ти-па-наследника доступность зависит от вида доступа в базовом типе.
Пример:
class X1{
int ix1; public: int f1(){... }
...
};
class Y1: protected X1 {
...
};
class Z1: public Y1 {
...
};
class X2{ protected:
int ix2; public:
int f2(){... }
...
};
class Y2: X2 {...};
class Z2: public Y2 {...};
В классе Y1 переменная ix1 недоступна непосредственно, так как она в базовом классе X1 находится в закрытой области. Однако она может быть ис-пользована в функции f1(). В то же время функция f1() не может использо-ваться в качестве внешнего метода по отношению к объекту, созданному на ос-нове класса Y1, так как она находится в защищенной области класса Y1. Это же остается справедливым и для класса Z1. В классе Y2 переменная ix2, в отличие от переменной ix1 в классе Y2, доступна непосредственно. В классе Z2 пере-менная ix2 становится недоступной для непосредственного использования, так же, как и переменная ix1 в классе Z1. Другие отличия классов Z1 и Z2: в отличие от функции f1() в классе Z1, функция f2() в классе Z2 доступна в классе Z2 качестве внутренней подпрограммы, только для функций, унаследованных из класса Y2, так как в классе Y2 она находится в закрытой области.
Закрытое наследование целесообразно в том случае, когда меняется сущ-ность нового объекта.
Пример: Базовый класс описывает фигуры на плоскости и имеет методывычисления площади фигур, а класс-наследник описывает объемные тела, на-пример, призмы с основанием – плоской фигурой, описываемой базовым классом. В этом случае объем тела, описываемого классом-наследником, вычисляется умножением площади основания на высоту. При этом не имеет значения, каким образом получена площадь основания. Кроме того, методы работы с объемными объектами отличны от методов работы с плоскими объектами. Поэтому в данном случае не имеет смысла наследование методов базового класса для работы с объектами, описываемыми классом-наследником:
#include <iostream> using namespace std;
class twom { double x,y;
public:
twom(double x1=1, double y1=1): x(x1), y(y1) {} double sq(){
return x*y;
}
};
class thm: private twom { double z; public:
thm(double x1 = 1, double y1 = 1, double z1 = 1):twom(x1,y1), z(z1){}
double vol(){ return sq()*z;}
};
int main(){
thm t1(1,2,3); double d1;
d1 = t1.vol();
cout << "vol= " << d1 << '\n'; return 0; }
Таким образом, закрытое наследование несколько напоминает композицию объектов, когда подобъект находится в закрытой области. Все же необходимо помнить, что наследование – это совсем другая концепция ассоциирования классов, по многим своим свойствам отличная от агрегации, даже в ее строгом варианте (композиции).
Перекрытие имен
В производном классе могут использоваться имена членов класса, пере-крывающие видимость таких же имен в базовом классе (overriding). При пере-крытии имен при работе с объектом через указатель будет исполняться тот метод, который содержится в классе, используемом в объявлении указателя, независимо от типа объекта, на который указывает указатель.
Пример:
#include <iostream> using namespace std;
class A { public:
void f(int x){
cout << "A::f" << '\n';
}
};
class C: public A{ public:
void f(int x){
cout << "C::f" << '\n';
}
pc = (C*)& a1; // Небезопасное преобразование указателя
// на объект базового класса к указателю
// на объект производного класса (данное
// преобразование должно объявляться // явно, иначе – ошибка).
pc -> f(1); // C::f – несмотря на то, что pa указывает
// на объект а1 типа класс А. В общем // случае такой вызов некорректен.
return 0;
}
Члены базового класса с именами, совпадающими с именами членов про-изводного класса, доступны в производном классе. Для доступа к ним необходимо указывать квалификатор (имя базового класса) с использованием операции ‘::’, так как данные члены находятся в доступной области видимости, которая не совпадает с текущей областью видимости. Также метод базового класса доступен через указатель класса-наследника при условии использования квалификатора.
Пример:
#include <iostream> using namespace std;
class A { public:
void f(int x){cout<<"A::f"<<'\n';}
};
class C: public A{ public:
void f(int x){
cout << "C::f" << '\n'; }
void g(){f(1); A::f(1);
}
};
int main(){C c1; C* pc; pc=&c1;
pc->A::f(1); // вызов метода базового класса с // использованием указателя
// класса–наследника.
pc->f(1); pc->g(); return 0;
}
Таким образом, при перекрытии методы базового класса не «затираются» в классе-наследнике. Они доступны через квалификатор.
|
||||||||||||||||||||||||||||||||||||||||
Последнее изменение этой страницы: 2017-02-05; просмотров: 160; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 13.59.34.87 (0.013 с.) |