Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву
Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Проблемы с одиночным наследованиемСодержание книги
Поиск на нашем сайте
Давайте продолжим работу над программой о животных и предположим, что в ней теперь используется два класса, произведенных от какого-то общего класса. Один — Bird, посвященный птицам, а другой — Mammals, посвященный млекопитающим. Класс Bird содержит функцию-член Fly(), задающую возможность полета. Класс Mammals разбит на ряд подклассов, включая класс лошадей — Horse. Класс содержит две функции- члена — Whinny() и Gallop(), объявляющих ржание и бег галопом соответственно. Но внезапно у вас возникает желание создать новый весьма интересный мифический объект — крылатого Пегаса (Pegasus), который был бы чем-то вроде гибрида между Horse и Bird. Сразу предупредим, что, используя только одиночное наследование, вам сложно будет справиться с этой задачей. Если объявить объект Pegasus как член класса Bird, то для него станут недоступными функции Whinny() и Gallop(). Если Pegasus объявить как объект класса Horse, то ему станет недоступной функция Fly(). Первое решение может состоять в том, чтобы скопировать метод Fly() в класс Horse, после чего в этом классе создать объект Pegasus. При этом оба класса (Bird и Horse) будут содержать один и тот же метод Fly(), и при изменении метода в одном классе нужно будет не забыть внести соответствующие изменения в другом классе. Хорошо, если таких классов будет только два. Если вам придется вносить изменения в программу через некоторое время после ее создания, будет сложно вспомнить, в каких еще классах представлен этот метод. Когда вы захотите создать списки объектов классов Bird и Horse, перед вами возникнет еще одна проблема. Хотелось бы, чтобы объект Pegasus был представлен в обоих списках, но в данном случае это невозможно. Для решения возникшей проблемы можно использовать несколько подходов. Haпример, можно переименовать слишком "лошадиный" метод Gallop() в более обтекаемый Move(), после чего заместить этот метод в объекте Pegasus таким образом, чтобы он выполнял функцию метода Fly(). В других объектах класса Horse метод Move() будет выполняться так же, как раньше выполнялся метод Gallop(). Для объекта Pegasus можно даже определить, что короткие дистанции он должен преодолевать методом Gallop(), а длинные — методом Fly(): Pegasus::Move(long distance) { if (distance > veryFar) fly(distance); else gallop(distance); } Но и этот подход имеет ряд ограничений, поскольку объект уже не сможет летать на короткие дистанции и бегать на длинные. Может быть, все же просто перенести метод Fly() в класс Horse, как показано в листинге 13.1? Проблема состоит в том, что лошади, в большинстве своем, летать не умеют, поэтому во всех объектах этого класса, за исключением объекта Pegasus, данный метод не должен ничего выполнять. Листинг 13.1. Умеют ли лошади летать... 1: // Листинг 13.1. Умеют ли лошади летать... 2: // Фильтрация метода Fly() в классе Horse 3: 4: #include <iostream.h> 5: 6: class Horse 7: { 8: public: 9: void Gallop(){ cout << "Galloping...\n"; } 10: virtual void Fly() { cout << "Horses can't fly.\n"; } 11: private: 12: int itsAge; 13: }; 14: 15: class Pegasus: public Horse 16: { 17: public: 18: virtual void Fly() { cout << "I can fly! I can fly! I can fly!\n"; } 19: }; 20: 21: const int NumberHorses = 5; 22: int main() 23: { 24: Horse* Ranch[NumberHorses]; 25: Horse* pHorse; 26: int choice,i; 27: for (i=0; i<NumberHorses; i++) 28: { 29: cout << "(1)Horse (2)Pegasus: "; 30: cin >> choice; 31: if (choice == 2) 32: pHorse = new Pegasus; 33: else 34: pHorse = new Horse; 35: Ranch[i] = pHorse; 36: } 37: cout << "\n"; 38: for (i=0; i<NumberHorses; i++) 39: { 40: Ranch[i]->Fly(); 41: delete Ranch[i]; 42: } 43: return 0; 44: }
Результат: (1)Horse (2)Pegasus; 1 (1)Horse (2)Pegasus: 2 (1)Horse (2)Pegasus: 1 (1)Horse (2)Pegasus: 2 (1)Horse (2)Pegasus: 1 Horses can't fly. I can fly! I can fly! I can fly! Horses can't fly. I can fly! I can fly! I can fly! Horses can't fly.
Анализ: Безусловно, эта программа будет работать ценой добавления в класс Horse редко используемого метода Fly(). Это произошло в строке 10. Для объектов данного класса этот метод констатирует факт, что лошади летать не умеют. И только для объекта Pegasus метод замещается в строке 18 таким образом, что при вызове его объект заявляет, что умеет летать. В строке 24 используется массив указателей на объекты класса Horse, с помощью которого метод Fly() вызывается для разных объектов класса. В зависимости от того, для какого из объектов в данный момент вызывается метод, программа выводит на экран разные сообщения.
Примечание: Показанный выше пример программы был значительно сокращен, чтобы выделить именно те моменты, которые сейчас рассматриваются. Так, для простоты программы из нее были удалены конструктор и виртуальные деструкторы.
|
||
|
Последнее изменение этой страницы: 2016-12-10; просмотров: 526; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 216.73.217.21 (0.009 с.) |