多态&接口
多态
<b>多态按字面的意思就是多种形态。</b>C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。Java 也分早期绑定和后期绑定,但是 C++ 的早期绑定与 Java 的不一样。
#include<iostream>
using namespace std;
class Shape {
public:
void say() { cout << "sha" << endl; }
};
class Rectangle : public Shape {
public:
void say() { cout << "rec" << endl; }
};
class Triangle : public Shape {
public:
void say() { cout << "tri" << endl; }
};
// 静态多态(早期绑定。而 Java 是 static 的才是早期绑定),函数调用在程序执行前就准备好了
int main() {
Shape *sr = new Rectangle;
Shape *st = new Triangle;
sr->say(); // sha
st->say(); // sha
}
需要使用 virtual 关键字来实现多态,在父类中使用关键字 <b>virtual</b> 声明的函数。在派生类中重新定义父类中定义的虚函数时,会告诉编译器不要静态链接到该函数。我们想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为<b>动态链接或后期绑定</b>。
#include<iostream>
using namespace std;
class Shape {
public:
virtual void say() { cout << "sha" << endl; }
};
class Rectangle : public Shape {
public:
void say() { cout << "rec" << endl; }
};
class Triangle : public Shape {
public:
void say() { cout << "tri" << endl; }
};
int main() {
Shape *sr = new Rectangle;
Shape *st = new Triangle;
sr->say();
st->say();
}
/*
rec
tri
*/
纯虚函数
我们可能想要在父类中定义虚函数,以便在子类中重新定义该函数更好地适用于对象,但是在父类中又不能对虚函数给出有意义的实现,这个时候就会用到纯虚函数。
#include<iostream>
using namespace std;
class Shape {
public:
virtual void say() = 0;
};
class Rectangle : public Shape {
public:
void say() { cout << "rec" << endl; }
};
class Triangle : public Shape {
public:
void say() { cout << "tri" << endl; }
};
int main() {
Shape *sr = new Rectangle;
Shape *st = new Triangle;
sr->say();
st->say();
}
接口
接口描述了类的行为和功能,而不需要完成类的特定实现。
C++ 接口是使用<b>抽象类</b>来实现的,抽象类与数据抽象互不混淆,数据抽象是一个把实现细节与相关的数据分离开的概念。
如果类中至少有一个函数被声明为纯虚函数,则这个类就是抽象类。纯虚函数是通过在声明中使用 "= 0" 来指定的,如下所示:
class Box {
public:
// 纯虚函数
virtual double getVolume() = 0;
private:
double length; // 长度
double breadth; // 宽度
double height; // 高度
};
设计<b>抽象类</b>(通常称为 ABC)的目的,是为了给其他类提供一个可以继承的适当的基类。抽象类不能被用于实例化对象,它只能作为<b>接口</b>使用。如果试图实例化一个抽象类的对象,会导致编译错误。
因此,如果一个 ABC 的子类需要被实例化,则必须实现每个虚函数,这也意味着 C++ 支持使用 ABC 声明接口。如果没有在派生类中重写纯虚函数,就尝试实例化该类的对象,会导致编译错误。
可用于实例化对象的类被称为<b>具体类</b>。
#include <iostream>
using namespace std;
// 基类
class Shape {
public:
// 提供接口框架的纯虚函数
virtual int getArea() = 0;
void setWidth(int w) {
width = w;
}
void setHeight(int h) {
height = h;
}
protected:
int width;
int height;
};
// 派生类
class Rectangle : public Shape {
public:
int getArea() {
return (width * height);
}
};
class Triangle : public Shape {
public:
int getArea() {
return (width * height) / 2;
}
};
int main(void) {
Rectangle Rect;
Triangle Tri;
Rect.setWidth(5);
Rect.setHeight(7);
// 输出对象的面积
cout << "Total Rectangle area: " << Rect.getArea() << endl;
Tri.setWidth(5);
Tri.setHeight(7);
// 输出对象的面积
cout << "Total Triangle area: " << Tri.getArea() << endl;
return 0;
}
/*
Total Rectangle area: 35
Total Triangle area: 17
*/