抽象类特性
1、抽象类不允许被实例化,只能被继承。
2、抽象类可以包含属性和方法。方法既可以包含代码实现,也可以不包含代码实现。不包含代码实现的方法叫做抽象方法。
3、子类继承抽象类,必须实现抽象类中的所有抽象方法。
接口特性
1、接口不能包含属性(也就是成员变量)
2、接口职能声明方法,方法不能包含代码实现
3、类实现接口的时候,必须实现接口中声明的所有方法。
抽象类的作用
1、代码复用
2、多态的优雅实现
关于第二点的具体解释:
继承不一定能够实现多态,继承+重写才能实现多态。
多态不一定需要抽象类,但是抽象类能够提升维护性和可读性。
如果某个方法是空实现而不是抽象类,子类可能忘记重写这个方法。
而且,一个空实现会让维护者感到奇怪。
接口的作用
解耦。接口是对行为的一种抽象,相当于一组协议。调用者只需要关注抽象的接口,而不需要了解具体的实现,可以降低代码间的耦合性。
C++通过抽象类模仿接口
C++只有抽象类,没有接口。
首先回顾之前的接口定义:
1、没有成员变量
2、只有方法声明,没有方法实现
3、实现接口的类必须实现接口中的所有方法
class Strategy { //用抽象类模拟接口
public:
~Strategy();
virtual void algorithm() = 0;
protected:
Strategy();
};
抽象类Strategy没有定义任何属性,并且所有方法都声明为virtual类型(等同于java的abstract关键字).这样所有的方法都不能有代码实现,并且每个继承这个抽象类的子类都要实现这个方法。
从语法特性上来说,这个抽象类就相当于一个接口
使用普通类实现接口
将构造函数从public修改为protected,在方法实现中抛出异常,强制子类必须实现父类中的方法。
下面,使用java中的普通类来模拟接口
public class MockInteface {
protected MockInteface() {}
public void funcA() {
throw new MethodUnSupportedException();
}
}
MethodUnSupportedException异常,来模拟不包含实现的接口,并且能够强迫子类在继承这个父类的时候都主动实现父类的方法,否则就会在运行的时候抛出异常。
两者区别
接口与抽象的重要区别,出去语法特征,最重要的是概念上,抽象更像是一种类的定义,而接口更像是协议。前者是属于和继承的关系,而接口是包含和具有的关系。
抽象:is-a
接口:has-a,表示具有某些功能。
从类的继承层次上来看,抽象类是一种自下而上的设计思路,现有子类的代码重复,再抽象成上层的父类。接口相反,是一种自上而下的设计思路,一般是先设计接口,再去考虑具体实现。