一个类的层次结构代表了一组封层组织的概念。基类通常有两种用途。一种通常被称为接口继承。另一种是实现继承。
接口继承使用公共继承。它把用户和实现分开。允许派生类增加或改变基类的功能而不影响基类的用户。
例如,如果你从Ball(球)类公共派生出Handball类,那么可以使用Handball来代替Ball.一个Handbal也是一个Ball。这一原则被称为Liskov替换原则。
实现继承经常使用私有继承。在典型情况下,派生类通过调整基类的功能来提供其功能。
接口隔离原则:
类模板Container打破了接口隔离原则,接口隔离原则指出。任何客户端(如派生类)都不应该被迫依赖于它不使用的成员函数。在类模板Container这个具体案例中,每个实现接口的类都必须实现所有的抽象方法。
接口隔离原则将那些太大,由太多成员函数组成的接口分割成更小、更具体的接口。
1.如果基类被当做接口使用,那就把它变成抽象类
抽象类是至少有一个纯虚函数的类,纯虚函数是必须由派生类实现的函数(除非派生类也是抽象类)。一个抽象类不能被实例化。
接口通常应该由公共的纯虚函数组成,没有数据成员,并且有默认/空的虚析构函数(virtual ~My_interface() = default)
2.当需要完全分离接口和实现时,以抽象类作为接口
抽象类的目的就是分离接口和实现、如果类的客户只依赖于接口Device,它就可以在运行时使用不同的实现。此外,对实现的修改不一定会影响接口,因而也可以不影响应用程序。
struct Device
{
virtual ~Device() = default;
virtual void write(span<const char> outbuf) = 0;
virtual void read(span<char> inbuf) = 0;
};
class Mouse : public Device
{
//... 数据...
virtual void write(span<const char> outbuf) override;
virtual void read(span<char> inbuf) override;
};
class TouchScreen : public Device
{
//... 数据...
virtual void write(span<const char> outbuf) override;
virtual void read(span<char> inbuf) override;
};