一.多态定义及实现
1.1概念
具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。
举个栗子:比如买票这个行为,当普通人买票时,是全价买票;学生买票时,是半价买票;军人买票时是优先买票。
多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。
1.2实现多态
多态条件:
- 前提:继承条件下;
- 父类存在虚函数,且子类完成该虚函数的重写。 函数重写:子类父类存在接口完全相同的函数(函数名,参数,返回值完全相同) 例外:协变
- 调用虚函数的类型必须是指针或者引用
- 一般使用父类对象的指针或引用指向子类对象.
- 多态:看指针/引用实际指向的对象是什么, 实际执行的就是对应对象的方法。
- 非多态看类型: 看指针/引用所代表的类型,是什么类型就执行对应类型的方法。
class Person
{
public:
//virtual 虚函数
virtual void buy()
{
cout << "全价票" << endl;
}
};
class Student : public Person
{
public:
virtual void buy()
{
cout << "Student 半价票" << endl;
}
};
class Teacher : public Person
{
public:
virtual void buy()
{
cout << "Teacher全价票" << endl;
}
};
void test()
{
Student s;
//非多态:值拷贝
Person ps = s;
ps.buy();//全价票
//多态: 引用执行虚函数
Person& rs = s;
rs.buy();//Student半价票
//多态: 指针执行虚函数
Person* pss = &s;
pss->buy();//Student半价票
Teacher t;
//多态: 引用执行虚函数
Person& rt = t;
rt.buy();//Teacher全价票
}
注意:
- 如果父类没有虚函数的声明,即使子类有虚函数的声明,子类和父类的对应函数构成函数隐藏,不是函数重写,所以不会产生多态行为。但是如果子类有对应的子类,子类的函数和子子类的函数会构成函数重写,会产生多态行为。总之只有继承体系的上层中有对应的虚函数,此体系中的对应函数就会产生多态行为。
- 如果父类有虚函数的声明,子类对应的函数就是虚函数,构成多态。
- 建议所以的虚函数都添加 virtual 的声明
class Person
{
public:
//virtual 虚函数
virtual void buy()
{
cout << "全价票" << endl;
}
};
class Student : public Person
{
public:
virtual void buy()
{
cout << "Student 半价票" << endl;
}
};
class Teacher : public Person
{
public:
virtual void buy()
{
cout << "Teacher全价票" << endl;
}
};
void Fun(Person p)//传的是值 ,不是引用或者指针,不构成多态
{
p.buy();
}
void test()
{
cout << "非多态" << endl;
Student s;
Person ps = s;
Teacher t;
Fun(ps);//全价票
Fun(s);//全价票
Fun(t);//全价票
cout << endl;
}
void Fun2(Person &p)//传的是引用或者指针,构成多态
{
p.buy();
}
void test2()
{
cout << "多态" << endl;
Student s;
Person ps = s;
Teacher t;
Fun2(ps);//全价票
Fun2(s);//Student半价票
Fun2(t);//Teacher全价票
cout << endl;
}
int main()
{
test();
test2();
system("pause");
return 0;
}
下面是协变下多态例子:
//协变场景下的多态
//函数名相同,参数相同,返回值类型不同-》比如构成父子关系的指针或引用
class A
{};
class B :public A
{};
class Person
{
public:
//virtual 虚函数
virtual A& buy()
{
cout << "全价票" << endl;
return A();
}
};
class Student : public Person
{
public:
virtual B& buy()
{
cout << "Student 半价票" << endl;
return B();
}
};
class Teacher : public Person
{
public:
virtual B& buy()
{
cout << "Teacher全价票" << endl;
return B();
}
};
void test2()