/*条款34:区分接口继承和实现继承*/
#include<iostream>
class Shape {
public:
virtual void draw()const = 0;
//声明一个纯虚函数的目的是为了让子类只继承函数接口 基类不必实现,但令人意外的,我们竞然可以为纯虚函数提供定义,但调用时它的唯一途径是明确指出其类名
//这种做法除了帮助你在鸡尾酒派对上留给大师级程序员一个深刻的印象,一般而言这甚项性质有限。。。
//virtual void error(const std::string&msg);
//声明简朴的非纯函数是让子类继承该函数的接口和缺省实现,如果子类不想重写就用缺省版本
//但缺省行为不一样是真的安全 比如继承的新的子类如果用缺少行为是不安全的情况
//1 就可以用下在保护属性下的非虚函数来实现,再把这里的error定义成纯虚
virtual void error(const std::string &msg) = 0;
int objectID()const;//
//非虚函数的目的是为了令子类继承函数的接口及一份强制性的实现
//..
protected:
void defaulterror() {
//...与上面的error函数相比,这里切断了 虚函数接口与缺省实现的连接
}
};
void Shape::draw()const {
//...
}
class Rectangle :public Shape {
void draw()const {
//is a 的关系 ,纯抽的原因,需要实现,不然也是纯抽类
}
void error(const std::string&msg) {
defaulterror();
}
};
class Ellipse:public Shape{
void draw()const {
//is a 的关系 ,纯抽的原因,需要实现,不然也是纯抽类
}
void error(const std::string&msg) {
defaulterror();
//这样子类就不会意外继承不正确的error实现代码了,因为纯虚函数必须提供实现
//第二种方法就是 定义基类纯函数的实现,不同点在他们的保护级别
}
};
using namespace std;
int main() {
//Shape *ps = new Shape;//抽象类不可以实例化
Shape*ps1 = new Rectangle;
ps1->draw();// Rectangle::draw
Shape*ps2 = new Ellipse;
ps2->draw();//Ellipse::draw
ps1->Shape::draw();//Shape::draw
ps2->Shape::draw();//Shape::draw
system("pause");
return 0;
}
// 接口继承和实现继承不同,在公有继承之下,子类总是继承基类的接口
//纯虚函数: 只具体指定接口继承
//非纯虚函数:具体指定接口继承与缺省实现继承
//非虚函数: 具体指定接口继承和强制性实现继承
条款34:区分接口继承和实现继承
最新推荐文章于 2022-12-22 22:05:31 发布