|
Программирование >> Дополнительные возможности наследования
28: void Draw(); 29: private: 30; int itsRadius; 31: int itsCircumference; 32: > ; 34; void Circle;:Draw() 35: { 36: cout Circle drawing routine here!\ n ; 37: Shape::DrawO; 38: } 41: class Rectangle : public Shape 42: { 43: public: 44: Rectangle(int len, int width): 45: itsLength(len), itsWidth(width){ } 46: virtual Rectangle(){ } 47: long GetAreaO { return itsLength itsWidth; } 48: long GetPerimO { return 2 itsLength + 2 itsWidth; } 49: virtual int GetLengthO { return itsLength; } 50: virtual int GetWidthO { return itsWidth; } 51: void Draw(); 52: private: 53; int itsWidth; 54: int itsLength; 55: } ; 57: void Rectangle::Draw() 58: { 59: for (int 1 = 0; KitsLength; i++) 60: { 61: for (int j = 0; j<itsWidth; j++) 62: cout x ; 64: cout \ n ; 65: } 66: Shape: :DrawO; 67: } 70: class Square : public Rectangle 71: { 72: public: 73: Square(int len); 74: Square(int len, int width); 75: virtual SquareO{ } 76: long GetPerimO { return 4 * GetLengthO;} 77: > ; Square::Square(int len): Rectangle(len,len) { } Square::Square(int len, int width): Rectangle(len,width) if (GetLengthO != GetWidthO) cout Error, not a square , a Rectangle??\ n ; int mainO { int choice; bool fOuit = false; Shape * sp; while (1) cout (l)Circle (2)Rectangle (3)Square (O)Quit: cin >> choice; switch (choice) { case 1 break; sp = new Circle(5); sp = new Rectangle(4,6); sp = new Square (5); case 2 break; case 3 break; default: fOuit = true; break; if (fOuit) break; sp->Draw(); delete sp; cout \ n ; return 0; (DCircle (2)Rectangle (3)Square (O)Quit: 2 X X X X X X X X X X X X X X X X X X , с X X X X X X vi!>. ,-.(,a. Abstract drawing mechanism! (l)Circle (2)Rectangle (3)Square (O)Quit; 3 X X X X X X X X X X X X X X X X X X X X X X X X X Abstract drawing mechanism! (l)Circle (2)Rectangle (3)Square (O)Quit: 0 В строках 5-14 объявляется класс абстрактного типа данных Shape с тремя ... чистыми виртуальными функциями. Впрочем, для того чтобы класс стал ADT, достаточно бьшо объявить в нем хотя бы один из методов как чистую виртуальную функцию. Далее в профамме все три функции базового класса замешаются в производных классах Circle и Rectangle, но одна из них - функция Draw() - выполняется как чистая виртуальная функция, поскольку в объявлении замещенного варианта функции в производных классах есть вызов исходной функции из базового класса. В результате выполнение этой функции в обоих производных классах приводит к выведению на экран одного и того же сообщения. Сложная иерархия аОстракций Иногда бывает необходимо произвести один класс ADT от другого класса ADT, например для того, чтобы в производном классе ЛОТ преобразовать в обычные методы часть функций, объявленных в базовом классе как чистые виртуальные, оставив при этом другие функции чистыми. Так, в классе Animal можно объявить методы Eat(), SleepO, Move() и Reproduce() как чистые виртуальные функции. Затем от класса Animal производятся классы Mammal и Fish. Исходя из соображения, что все млекопитающие размножаются практически одинаково, имеет смысл в классе Mammal преобразовать метод Reproduce() в обычный, оставив при этом методы Eat О, SleepO и Move() чистыми виртуальными функциями. Затем от класса Mammal производится класс Dog, в котором необходимо заместить все три оставшиеся чистые виртуальные функции, чтобы получить возможность создавать объекты класса Dog. Таким образом, наследование одного класса ADT от другого класса ADT позволяет объявлять общие методы для всех следующих производных классов, чтобы не замещать потом эти функции по отдельности в каждом производном классе. В листинге 13.10 показан базовый костяк профаммы, в котором используется объявленный выше подход. Аисшииг 13.10. НасАвдоваиив кдасси ADT от другого кдасса ADT Листинг 13.10, Deriving ADTs from other ADTs Sinclude <iostream.h> enum COLOR { Red, Green, Blue, Yellow, White, Black, Brown }
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |