前提:继承(实现)、覆盖(override)、向上转型。
目的:通过允许向上转型,实现动态绑定,在”不变“中实现“变化”。
原则:开闭原则。
实现:使用基类的引用或者指针,引用或者指向子类对象。这些不同的子类实现了一些基类中相同的方法,但各有自己的不同操作,在进行这些相同操作时,系统会根据实际引用和指向的对象,确定需要调用哪一个子类对象的那一个共同方法。
影响:实现了静态语言的动态绑定,解决参数传递只能传递指定类型的局限性,有利于实现开闭原则。
注意:在向上转型后,该引用不能调用子类对象独有的方法。解决方法:强制类型转换,不安全。
技术:虚函数指针,虚函数表,虚函数切片。
示例:C++,Java,Python的多态实现,Java的interface与abstract类的区别。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
#include<iostream>
class People { public: virtual void speak(){ std::cout << "People speak!" << std::endl; }; };
class Man: public People{ public: void speak(){ std::cout << "Man speak!" << std::endl; }; };
class Woman: public People{ public: void speak(){ std::cout << "Woman speak!" << std::endl; } };
void Func(People* people){ people->speak(); }
int main(){ People pp; pp.speak(); Man* man=new Man(); People* p =man; Func(p);
Woman woman; Func(&woman);
return 0; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #include<iostream>
class Human1 { public: virtual void eat()=0; virtual void sleep()=0; };
class Human2 { public: virtual void eat()=0; virtual void speak(){ std::cout << "Human speak!" << std::endl; } };
int main(int argc, const char** argv) {
return 0; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
class Creature: def eat(self): ... @staticmethod def staticmethod(): ...
class Human(Creature): def eat(self): print("Human eats something!")
class Animal(Creature): def eat(self): print("Animal eats something!")
def Func(creature): creature.eat()
Func(Human()) Func(Animal())
|