覆盖、重载和多态
覆盖:
在基类中定义了一个非虚拟函数,然后在派生类中又定义了一个同名同参数同返回类型的函数,这就是覆盖了。在派生类对象上直接调用这个函数名,只会调用派生类中的那个。
例如:
1 #include<iostream> 2 3 using namespace std; 4 5 /** 6 * 基类 7 */ 8 class Mammal{ 9 public: 10 11 void Speak() const { 12 cout<<"叫了一声"<<endl; 13 }; 14 }; 15 16 /** 17 * Dog类 18 */ 19 class Dog:public Mammal{ 20 public: 21 22 void Speak() const { 23 cout<<"旺旺"<<endl; 24 }; 25 }; 26 27 28 int main(){ 29 Dog dog; 30 dog.Speak(); 31 32 }
运行:
重载:
在基类中定义了一个非虚拟函数,然后在派生类中定义一个同名,但是具有不同的参数表的函数,这就是重载。在派生类对象上调用这几个函数时,用不同的参数会调用到不同的函数,有可能会直接调用到基类中的那个。
例如:
#include<iostream> using namespace std; /** * 基类 */ class Mammal{ public: void Speak() const { cout<<"叫了一声"<<endl; }; }; /** * Dog类 */ class Dog:public Mammal{ public: void Speak(int a) const { //加入形参 进行重载 cout<<"旺旺"<<endl; }; }; int main(){ Mammal mammal; mammal.Speak(); Dog dog; dog.Speak(1); }
运行:
多态:
在基类中定义了一个虚拟函数,然后在派生类中又定义一个同名,同参数表的函数,这就是多态。多态是这3种情况中唯一采用动态绑定技术的一种情况。也就是说,通过一个基类指针来操作对象,如果对象是基类对象,就会调用基类中的那个函数,如果对象实际是派生类对象,就会调用派声雷中的那个函数,调用哪个函数并不由函数的参数表决定,而是由函数的实际类型决定。
例如:
#include<iostream> using namespace std; /** * 基类 */ class Mammal{ public: virtual void Speak() const = 0; }; /** * Dog类 */ class Dog:public Mammal{ public: virtual void Speak() const; }; void Dog::Speak() const { cout<<"旺旺"<<endl; }; /** * cat类 * */ class Cat:public Mammal{ public: virtual void Speak() const; }; void Cat::Speak() const { cout<<"喵喵"<<endl; } /** * 测试函数 * @param mammal */ void test(Mammal* mammal) { mammal->Speak(); } int main(){ Dog dog; Cat cat; test( &dog); test( &cat); }
运行: