C++ за 21 день седьмое издание


называемые содержит (has-a). В окружающем мире есть множество примеров закрытого наследования (табл. 10.2)



Download 1,38 Mb.
bet187/437
Sana22.02.2022
Hajmi1,38 Mb.
#89455
TuriРеферат
1   ...   183   184   185   186   187   188   189   190   ...   437
Bog'liq
word1

называемые содержит (has-a). В окружающем мире есть множество примеров закрытого наследования (табл. 10.2).


ТАБЛИЦА 10.2. Примеры закрытого наследования из повседневной жизни



Базовый класс


Примеры производных классов



Motor (Мотор)


Heart (Сердце)


Refill (Стержень)


Moon (Луна)


Саг (Автомобиль содержит мотор)


Mammal (Млекопитающее содержит сердце)


Реп (Ручка содержит стержень)


Sky (Небо содержит луну)



Давайте рассмотрим закрытое наследование на примере отношений автомобиля с его мотором (листинг 10.8).


ЛИСТИНГ 10.8. Класс Саг, связанный с классом Motor через закрытое наследование



  1. #include




  1. using namespace std;


  2. class Motor




  1. {




  1. public:




  1. void Switchlgnition()

  2. {



8 cout « "Ignition ON" « endl;

  1. }




  1. void PumpFuelO




  1. {

  2. cout « "Fuel in cylinders" « endl;




  1. }




  1. void FireCylinders()




  1. {




  1. cout « "Vroooom" « endl;




  1. }




  1. };



19



  1. class Car:private Motor

  2. {

  3. public:




  1. void Move ()




  1. {




  1. Switchlgnition();




  1. PumpFuel();




  1. FireCylinders();




  1. }




  1. };



30



  1. int main()




  1. {




  1. Car myDreamCar;




  1. myDreamCar.Move();








  1. return 0;




  1. }

Защищенное наследование

267



Результат


Ignition ON


Fuel in cylinders


Vroooom


Анализ


Класс M otor, определенный в строках 3-18, очень прост, он содержит три защищен­ ные функции-члена, включая зажигание ( S w i t c h l g n i t i o n O ) , подачу топлива (Pump F uel ()) и запуск ( F ir e C y lin d e r s ()). Класс С аг наследует класс M otor с использовани­ ем ключевого слова p r i v a t e (строка 20). Таким образом, открытая функция C a r : :Move () обращается к членам базового класса M otor. Если вы попытаетесь вставить в функцию



  1. a in ( ) строку myDreamCar.PumpFuel();

то получите при компиляции ошибку с сообщением e r r o r С 2 247 : M o to r : : Pum pFuel





T ct a c c e s s i b l e b e c a u s e C2247: M o to r : : Pum pFuel следовании от ' M o to r ').


’C a r ’ u s e s 'p r i v a t e '




недоступен, поскольку

to i n h e r i t fro m 'M o to r '


'C a r ' использует 'p r i v a t e '




(ошибка при на­



ПРИМЕЧАНИЕ
Если от класса Саг произойдет другой класс, например SuperCar, то, неза­ висимо от характера наследования, у класса SuperCar не будет доступа к от­

крытым членам и методам базового класса Motor. Дело в том, что отношения наследования между классами Саг и Motor имеют закрытый характер, а зна­ чит, доступ для всех остальных, кроме класса Саг, будет закрытым (т.е. доступа не будет), даже к открытым членам базового класса.


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


Защищенное наследование


Защищенное наследование отличается от открытого наличием ключевого слова p r o ­ je c te d в строке объявления производного класс как происходящего от базового класса:


class Base


{


// ... переменные-члены и методы базового класса
};


class Derived: protected Base // защищенное наследование

{
// ... переменные-члены и методы производного класса


};


Защищенное наследование подобно закрытому в следующем:

Реализует отношения содержит (has-a).



268 ЗАНЯТИЕ 10. Реализация наследования



  1. Позволяет производному классу обращаться ко всем открытым и защищенным членам базового.




  1. Вне иерархии наследования нельзя при помощи экземпляра производного класса об­ ратиться к открытым членам базового класса.

Но защищенное наследование все же отличается от закрытого, когда дело доходит до следующего производного класса, унаследованного от него:




class Derived2: protected Derived

{
// имеет доступ к членам Base


};


Иерархия защ ищ енного наследования позволяет производному классу производно­ го класса (т.е. классу D e riv e d 2 ) обращаться к открытым членам базового класса (ли­ стинг 10.9). Это не было бы возможно, если бы при наследовании классом D e riv e d класса B ase использовалось ключевое слово p r i v a t e .

ЛИСТИНГ 10.9. Класс SuperCar, производный от класса Саг,


происходящего от класса Motor, при защищенном наследовании________________________





  1. #include




  1. using namespace std;



2 :

  1. class Motor




  1. {




  1. public:




  1. void Switchlgnition()




  1. {

  2. cout « "Ignition ON" « endl;




  1. }

  2. void PumpFuelO



11: {

  1. cout « "Fuel in cylinders" « endl;




  1. }




  1. void FireCylinders()




  1. {




  1. cout « "Vroooom" « endl;




  1. }




  1. };



19:



  1. class Car:protected Motor



21: {

  1. public:




  1. void Move()




  1. {




  1. Switchlgnition();




  1. PumpFuelO;




  1. FireCylindersО ;




  1. }




  1. };



30:



  1. class SuperCar:protected Car




  1. {




  1. public:




  1. void Move()

Защищенное наследование

269




  1. {




  1. Switchlgnition(); // имеет доступ к членам базового благодаря



27: PumpFuelO; // защищенному наследованию между Саг и Motor



  1. FireCylinders();




  1. FireCylinders();



4 9:FireCylinders ();
41: }
42: };


43:


44: int main()


45: {



  1. SuperCar myDreamCar;




  1. myDreamCar.Move();








  1. return 0;

- 3: }



Результат


Ignition ON


Fuel in cylinders


Vroooom


Vroooom


Vroooom


Анализ

Класс C a r защ ищ енно наследует класс M o to r (строка 20). Класс S u p e r C a r за­ щищенно наследует класс С аг (строка 31). Как можно заметить, реализация метода


S u p e rC a r: :Move () использует открытые методы, определенные в базовом классе Мо-7or. Этот доступ к самому первому базовому классу M otor через промежуточный базо­ вый класс Саг обеспечивают отношения между классами Саг и M otor. Если бы это было закрытое наследование, а не защищенное, то у производного класса не было бы доступа





  1. открытым членам M o to r, поскольку компилятор выберет самый ограничивающ ий из использованных модификаторов доступа. Обратите внимание, что характер отношений между классами Саг и S u p e rC a r не имеет значения при доступе к базовому классу. Так,

даже если в строке 31 заменить ключевое слово p r o t e c t e d на p u b l i c или p r i v a t e , ис­ ход компиляции этой программы остается неизменным.







ВНИМАНИЕ!

Используйте закрытое или защищенное наследование только по мере необхо­ димости.



В большинстве случаев, когда используется закрытое наследование (как у классов Саг и Motor), базовый класс также может быть атрибутом (членом) класса Саг, а не суперклассом. При наследовании от класса Motor вы, по существу, огра­ ничили свой класс Саг наличием только одного мотора, без какого-либо суще­ ственного выигрыша от наличия экземпляра класса Motor как закрытого члена.


Автомобили развиваются, и сейчас не редкость гибридные автомобили, напри­ мер, в дополнение к обычному мотору может применяться газовый или элек­ трический. Наша иерархия наследования для класса Саг оказалась бы узким местом, попытайся мы последовать за такими разработками.



270 ЗАНЯТИЕ 10. Реализация наследования



ПРИМЕЧАНИЕ
Наличие экземпляра класса Motor как закрытого члена, вместо наследования от него, называется композиция (composition) или объединение (aggregation). Такой класс Саг выглядел бы следующим образом:



class Саг


{


private:


Motor heartOfCar;


public:


void Move()
{
heartOfCar.Switchlgnition ();


heartOfCar.PumpFuel();


heartOfCar.FireCylinders();
}
};

Это может быть хорошим ходом, поскольку позволяет легко добавлять к суще­ ствующему классу Саг больше моторов как атрибутов, не изменяя его иерар­ хию наследования или предоставляемые клиентам возможности.


Проблема отсечения

Что будет, если программист сделает следующее?




Derived objectDerived;


Base objectBase = objectDerived;

Или следующее?




void FuncUseBase(Base input);


Derived objectDerived;


FuncUseBase(objectDerived); // objectDerived будет отсечен при




Download 1,38 Mb.

Do'stlaringiz bilan baham:
1   ...   183   184   185   186   187   188   189   190   ...   437




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©hozir.org 2024
ma'muriyatiga murojaat qiling

kiriting | ro'yxatdan o'tish
    Bosh sahifa
юртда тантана
Боғда битган
Бугун юртда
Эшитганлар жилманглар
Эшитмадим деманглар
битган бодомлар
Yangiariq tumani
qitish marakazi
Raqamli texnologiyalar
ilishida muhokamadan
tasdiqqa tavsiya
tavsiya etilgan
iqtisodiyot kafedrasi
steiermarkischen landesregierung
asarlaringizni yuboring
o'zingizning asarlaringizni
Iltimos faqat
faqat o'zingizning
steierm rkischen
landesregierung fachabteilung
rkischen landesregierung
hamshira loyihasi
loyihasi mavsum
faolyatining oqibatlari
asosiy adabiyotlar
fakulteti ahborot
ahborot havfsizligi
havfsizligi kafedrasi
fanidan bo’yicha
fakulteti iqtisodiyot
boshqaruv fakulteti
chiqarishda boshqaruv
ishlab chiqarishda
iqtisodiyot fakultet
multiservis tarmoqlari
fanidan asosiy
Uzbek fanidan
mavzulari potok
asosidagi multiservis
'aliyyil a'ziym
billahil 'aliyyil
illaa billahil
quvvata illaa
falah' deganida
Kompyuter savodxonligi
bo’yicha mustaqil
'alal falah'
Hayya 'alal
'alas soloh
Hayya 'alas
mavsum boyicha


yuklab olish