PHP接口和抽象类有什么区别?

答案

相同点:

  • 都是抽象类,都不能实例化

  • interface 实现类及 abstract class 的子类都必须要实现已经声明的抽象方法。

区别:

  • 定义接口用 interface 关键词;定义抽象类用 abstract class

  • 接口需要实现,要用 implements ;抽象类需要继承,要用 extends

  • 接口中的每一个方法都是抽象方法,都只是声明的,没有方法体,实现类必须要实现。而抽象类的子类可以有选择地实现

  • 接口没有数据成员;抽象类可以有数据成员,实现数据的封装。

  • 接口没有构造函数;抽象类可以有构造函数。

  • 接口的方法都是public类型,而抽象类中的抽象方法可以是protectedpublic,但不能为private

  • 一个类可以同时实现多个接口,但是只能继承一个抽象类

答案解析

抽象类中的子类可以有选择地实现抽象类,有两点含义:

  • 抽象类中并非所有的方法都是抽象的,只有那些冠有 abstract 的方法才是抽象的,子类必须实现。那些没有 abstract 的方法,在 abstract class必须定义方法体

  • 抽象类的子类在继承它时,对非抽象方法既可以直接继承,也可以覆盖;而对抽象方法,可以选择实现,也可以留给其子类来实现,但此类必须也声明为抽象类。既是抽象类,当然也不能实例化

抽象类是 interfaceclass 的中介,抽象类在接口和 class 中起到了承上启下的作用。

  • 一方面,abstract class 是抽象的,可以声明抽象方法,以规范子类必须实现的功能;

  • 另一方面,它又可以定义缺省的方法体,供子类直接使用或覆盖;

  • 另外,它还可以定义自己的实例变量,以供子类通过继承来使用。

接口中的抽象方法前不用也不能加 abstract 关键字,默认隐式就是抽象方法,也不能加 final 关键字来防止抽象方法的继承。而抽象类中抽象方法前则必须加上 abstract 表示显示声明为抽象方法。

参考资料