多态的介绍
多种形态,同一行为,当不同的对象去完成时会产生出不同的状态。比如:需要出行时,有的人会坐火车,有的人会坐飞机
静态多态:在编译时就可以确定对象的使用,比如:函数重载,同一个函数名不同形参,调用形式各种各样。---编译时实现
多半一般指动态多态。
动态多态:一个父类的引用或指针去调用同一个函数,传递不同的对象,会调用不同的函数。 ---运行时实现
int add(int a,int b) // addii
{
return a + b;
}
int add(int a) // addi
{
return a + 5;
}
add(3,5);
add(6);
多态实现:虚函数、抽象类、覆盖、模板
多态构成多态的条件
1.必须通过基类的指针或者引用调用"""虚函数"""。
2.被调用的函数必须是虚函数,且派生类 必须对基类的虚函数进行重写。
3.积累使用了虚函数,基类的派生类中同名函数也自动成为了虚函数
虚函数:
被virtual修饰的成员函数,不能是静态成员或普通函数,不能是构造函数
格式:
class 类名
{
virtual 类型 函数名(形参)
{
}
};
通过对虚函数重写实现多态。
#include<iostream>
using namespace std;
class Person
{
public:
// 成员数据
int age;
// 构造函数
Person(int a=0)
{
age = a;
}
// 虚函数
virtual void show()
{
cout << "人类:age-" << age << endl;
}
};
class Student:public Person
{
public:
Student(int x=0)
{
age = x;
}
void show()
{
cout << "学生:age" << age << endl;
}
};
class Teacher:public Person
{
public:
Teacher(int x=0)
{
age = x;
}
void show()
{
cout << "老师:age" << age << endl;
}
};
// 函数
void test(Person *pp)
{
// 这个函数对于老师或者学生都可以用,
// 如果传递的是老师对象就用老师的show
// 如果传递学生对象就用学生的show
// 形参怎么写?
pp->show();
}
int main()
{
Teacher t(30);
Student s(23);
Person *p = &t;
p->show();
p = &s;
p->show();
test(&t);
test(&s);
Person a;
test(&a);
return 0;
}#include<iostream>
using namespace std;
//打印机单例模式
class Printer {
public:
//对外接口
static Printer* getInstance() {
return printer;
}
//打印功能
void printText(string text) {
cout << text << endl;
}
private:
// 构造函数私有化
Printer() {};
Printer(const Printer& p) {};
//类内声明对象指针
static Printer* printer;
};
//类外初始化
Printer* Printer::printer = new Printer;
int main()
{
Printer *p = Printer::getInstance();
p->printText("hello world");
Printer *p1 = Printer::getInstance();
p1->printText("hello world");
cout << p << p1 << endl;
return 0;
}
抽象类
抽象类的定义就是,含有”“ "纯虚函数" ""的类,可以包含多个虚函数。
纯虚函数:当在基类无法为虚函数提供任何有实际意义的定义时,可以将虚函数声明为纯虚函数,它的实现留给派生类去做。
此外,只定义了protected或private型构造函数的类也是抽象类,不能通过类名 + 对象名创建对象,只能通过静态成员方法的形式创建对象
抽象类
1、包含纯虚函数的类
2、构造函数写在protected和private权限下。
纯虚函数
纯虚函数的格式:
class 类名
{
virtual 类型 函数名(形参) = 0;
};
纯虚函数不能直接被调用,他只提供了一个接口,子类必须实现这个接口。
注意:
1、纯虚函数必须要在子类里面实现
2、包含纯虚函数的类叫抽象类,不能用抽象类创建对象
抽象类拓展:单例模式
只定义了protected或private型构造函数的抽象类
例子:实现单例模式 --- 保证整个系统中一个类只有一个兑现的实例,实现这种功能的方式就叫单例模式
#include<iostream>
using namespace std;
// 多态
// 抽象类是实现多态的一种解决办法
// 抽象类:包含純虚函数的类,如果构造函数写在protected或者private权限中也是抽象类。
// 单例模式是 构造函数写在protected或者private权限中的抽象类 的一个具体应用。
// 单例模式:一个类只有一个对象,实现的时候 将构造函数写在protected或者private权限中的抽象类
// 单例模式的应用场景:实现多线程获取同一个对象,一般用日志管理或者缓存管理
// 使用一个打印机 的单例模式
class Printer
{
public:
// 静态成员函数
static Printer *getInstance(void)
{
return p;
}
// 测试成员函数
void show()
{
cout << "我是打印机" << endl;
}
~Printer()
{
delete p;
p = NULL;
}
private:
// 构造函数 和复制构造函数
Printer(){}
Printer(const Printer &p){}
// 静态的打印机对象指针
static Printer *p;
};
Printer *Printer::p = new Printer;
int main()
{
Printer *p = Printer::getInstance();
p->show();
Printer *p1 = Printer::getInstance();
p1->show();
cout << p << p1 << endl;
return 0;
}
总结
目标:一个类只有一个对象
1、把构造函数和赋值构造函数封掉 --- private
2、给他开放个接口 --- 需要定义静态的成员,用静态成员构造对象,在这个接口里面返回这个对象
在接口里面需要对静态成员进行访问,所以这个接口只能写成静态成员函数。
3、使用接口函数获取对象,使用其他功能。