48.纯虚函数和抽象类
1.纯虚函数和多继承
多继承带来了一些争议,但是接口继承可以说一种毫无争议的运用了。
绝大数面向对象语言都不支持多继承,但是绝大数面向对象对象语言都支持接口的概念,c++中没有接口的概念,但是可以通过纯虚函数实现接口。
接口类中只有函数原型定义,没有任何数据定义。
多重继承接口不会带来二义性和复杂性问题。接口类只是一个功能声明,并不是功能实现,子类需要根据功能说明定义功能实现。
注意:除了析构函数外,其他声明都是纯虚函数。
2.纯虚函数和抽象类(重点)
1.依赖倒转
业务层依赖抽象层,实现层依赖抽象层
//抽象层
class rule
{
public:
virtual int getnum(int a,int b)
{
return 0;
}
};
//实现层
class plus_rule :public rule
{
public:
virtual int getnum(int a, int b)//重写父类的虚函数,依赖抽象层
{
return a+b;
}
};
//业务层
int doLogin(rule *cal)
{
int a = 10;
int b = 20;
int ret=cal->getnum(a, b);//依赖抽象层
return ret;
}
void test()
{
rule *r = NULL;
r = new plus_rule;
cout << doLogin(r) << endl;
delete r;
}
2.开闭原则
对修改源代码关闭,对扩展新功能开放
//抽象层
class rule
{
public:
virtual int getnum(int a,int b)
{
return 0;
}
};
//实现层
class plus_rule :public rule
{
public:
virtual int getnum(int a, int b)//重写父类的虚函数,依赖抽象层
{
return a+b;
}
};
//扩展新功能
class miux_rule :public rule
{
public:
virtual int getnum(int a, int b)
{
return a - b;
}
};
//业务层
int doLogin(rule *cal)
{
int a = 10;
int b = 20;
int ret=cal->getnum(a, b);//依赖抽象层
return ret;
}
void test()
{
rule *r = NULL;
r = new plus_rule;
cout << doLogin(r) << endl;
delete r;
//增加的代码
r = new miux_rule;
cout << doLogin(r) << endl;
delete r;
}
3.纯虚函数
class rule
{
public:
//纯虚函数
virtual int getnum(int a, int b) = 0;
};
4.抽象类
1.有纯虚函数的类叫抽象类,不能实例化对象
//有纯虚函数的类叫抽象类,不能实例化对象
class rule
{
public:
//纯虚函数
virtual int getnum(int a, int b) = 0;
};
void test02()
{
//抽象类不能实例化对象
//rule r;
}
2.如果子类继承抽象类,子类必须实现抽象类的所有纯虚函数,不然子类也变为抽象类
class Maker
{
public:
virtual void func1() = 0;
virtual void func2() = 0;
};
class Son :public Maker
{
public:
virtual void func1()
{
}
virtual void func2()
{
}
};
void test03()
{
Son s;
}
3.视频内容
程序1:
#pragma warning(disable:4996)
#define _CRT_SECURE_NO_WARNINGS 1
//2022年10月18日21:18:48
#include <iostream>
using namespace std;
class rule
{
public:
virtual int getnum(int a, int b)
{
return 0;
}
};
//实现层
class plus_rule:public rule
{
public:
virtual int getnum(int a, int b)
{
return a + b;
}
};
//业务层
int dogLogin(rule *cal)
{
int a = 10;
int b = 20;
int ret = cal->getnum(a, b);
return ret;
}
void test()
{
rule *r = NULL;
r = new plus_rule;
cout << dogLogin(r) << endl;
delete r;
}
int main()
{
test();
system("pause");
return EXIT_SUCCESS;
}
输出结果:
30
请按任意键继续. . .
程序2:
#pragma warning(disable:4996)
#define _CRT_SECURE_NO_WARNINGS 1
//2022年10月18日21:18:48
#include <iostream>
using namespace std;
//抽象层
//有纯虚函数的类叫抽象类,不能实例化出对象
class rule
{
public:
virtual int getnum(int a, int b) = 0;//纯虚函数
};
//实现层
class plus_rule:public rule
{
public:
virtual int getnum(int a, int b)//重写父类的虚函数,依赖抽象层
{
return a + b;
}
};
class miux_rule:public rule
{
public:
virtual int getnum(int a, int b)
{
return a - b;
}
};
//业务层
int dogLogin(rule *cal)
{
int a = 10;
int b = 20;
int ret = cal->getnum(a, b);//依赖抽象层
return ret;
}
void test()
{
rule *r = NULL;
r = new plus_rule;
cout << dogLogin(r) << endl;
delete r;
r = new miux_rule;
cout << dogLogin(r) << endl;
delete r;
}
void test02()
{
//抽象类不能实例化对象
//rule r;//err
}
int main()
{
test();
system("pause");
return EXIT_SUCCESS;
}
输出结果:
30
-10
请按任意键继续. . .
4.接口的定义(了解)
1.所谓的接口,即将内部实现细节封装起来,外部用户用过预留的接口可以使用接口的功能而不需要知晓内部具体细节。C++中,通过类实现面向对象的编程,而在基类中只给出纯虚函数的声明,然后在派生类中实现纯虚函数的具体定义的方式实现接口,不同派生类实现接口的方式也不尽相同
//抽象类
class Father
{
public:
virtual void func1() = 0;//接口的声明
virtual void func2(int a) = 0;
virtual void func3(int a,int b) = 0;
};
class Son :public Father
{
public:
virtual void func1()//接口的实现
{
}
virtual void func2(int a)
{
}
virtual void func3(int a, int b)
{
}
};
参考资料
参考资料来源于黑马程序员等