面向对象 的三大特征为:封装、继承 和多态,这三种机制能够有效提高程序的可读性、可扩充性和可重用性。“多态(polymorphism)” 指的是同一名字的事物可以完成不同的功能。
多态可以分为编译时的多态和运行时的多态。前者主要是指 函数的重载(包括运算符的重载)、对重载函数的调用,在编译时就能根据实参确定应该调用哪个函数,因此叫编译时的多态;而后者则和继承、虚函数等概念有关。
有了虚函数,基类指针指向基类对象时就使用基类的成员(包括 成员函数 和 成员变量 ),指向派生类对象时就使用派生类的成员。换句话说,基类指针可以按照基类的方式来做事,也可以按照派生类的方式来做事,它有多种形态,或者说有多种表现方式,我们将这种现象称为多态(Polymorphism)。
C++ 提供多态的目的是:可以通过基类指针对所有派生类(包括直接派生和间接派生)的成员变量和成员函数进行 “全方位” 的访问,尤其是成员函数。如果没有多态,我们只能访问成员变量。
C++多态的使用
#include <iostream>
#include <cstring>
using namespace std;
//Person类
class Person
{
public:
Person(string name, int age):m_name(name),m_age(age)
{
}
void info()
{
cout << "Call Person info, Name = " << this->m_name << " Age = " << this->m_age << endl;
}
protected:
string m_name;
int m_age;
};
class Student:public Person
{
public:
Student(string name, int age, float score):Person(name, age),m_score(score)
{
}
void info()
{
cout << "Call Student info, Name = " << this->m_name << " Age = " << this->m_age << " Score = " << m_score << endl;
}
protected:
float m_score;
};
int main()
{
cout << "嗨客网(www.haicoder.net)\n" << endl;
Person *person = new Person("HaiCoder", 18);
person->info();
Student *student = new Student("HaiCoder", 18, 99);
student->info();
return 0;
}
程序运行后,控制台输出如下:
我们分别定义了一个 Person 类和一个 Student 类,Student 类继承自 Person 类,接着,在 main 函数里面,我们分别实例化了一个 Person 对象和一个 Student 对象。
最后,我们分别调用了 Person 类对象的 info 方法和 Student 类对象的 info 方法,我们发现,它们各自调用了自己的 info 函数,现在,我们用 Student 来实例化 Person 类,我们修改程序,如下:
#include <iostream>
#include <cstring>
using namespace std;
//Person类
class Person
{
public:
Person(string name, int age):m_name(name),m_age(age)
{
}
void info()
{
cout << "Call Person info, Name = " << this->m_name << " Age = " << this->m_age << endl;
}
protected:
string m_name;
int m_age;
};
class Student:public Person
{
public:
Student(string name, int age, float score):Person(name, age),m_score(score)
{
}
void info()
{
cout << "Call Student info, Name = " << this->m_name << " Age = " << this->m_age << " Score = " << m_score << endl;
}
protected:
float m_score;
};
int main()
{
cout << "嗨客网(www.haicoder.net)\n" << endl;
Person *person = new Person("HaiCoder", 18);
person->info();
person = new Student("HaiCoder", 18, 99);
person->info();
return 0;
}
程序运行后,控制台输出如下:
这次,我们用 Student 类实例化了 Person 类,最终调用 info 函数,此时的 info 函数还是调用的 Person 类的,这不是我们想要的效果,我们期望的是还是调用 Student 类的 info 函数。
也就是说通过基类指针只能访问派生类的成员变量,但是不能访问派生类的成员函数。为了能让基类指针访问派生类的成员函数,C++ 增加了虚函数(Virtual Function),现在,我们将 info 函数声明为虚函数,修改程序如下:
#include <iostream>
#include <cstring>
using namespace std;
//Person类
class Person
{
public:
Person(string name, int age):m_name(name),m_age(age)
{
}
virtual void info()
{
cout << "Call Person info, Name = " << this->m_name << " Age = " << this->m_age << endl;
}
protected:
string m_name;
int m_age;
};
class Student:public Person
{
public:
Student(string name, int age, float score):Person(name, age),m_score(score)
{
}
virtual void info()
{
cout << "Call Student info, Name = " << this->m_name << " Age = " << this->m_age << " Score = " << m_score << endl;
}
protected:
float m_score;
};
int main()
{
cout << "嗨客网(www.haicoder.net)\n" << endl;
Person *person = new Person("HaiCoder", 18);
person->info();
person = new Student("HaiCoder", 18, 99);
person->info();
return 0;
}
程序运行后,控制台输出如下:
这次,我们使用 person 对象可以调用到 Student 实例的 info 方法了,即,我们通过虚函数实现了多态。
基类指针可以按照基类的方式来做事,也可以按照派生类的方式来做事,它有多种形态,或者说有多种表现方式,我们将这种现象称为多态(Polymorphism)。
C++ 提供多态的目的是:可以通过基类指针对所有派生类(包括直接派生和间接派生)的成员变量和成员函数进行 “全方位” 的访问,尤其是成员函数。如果没有多态,我们只能访问成员变量。