MENU

PHP 抽象类和接口

May 12, 2021 • Read: 1641 • PHP,编码

抽象类是什么

  • 抽象类是一种特殊的类,使用abstract修饰
  • 抽象类不能被实例化,只能被继承
  • 抽象方法不能设置使用private 修饰,因为抽象类不能被实例化,私有成员没有意义。
  • abstract 还可以修饰方法,称之为抽象方法:抽象方法所在的类必须是抽象类,抽象方法不能有方法体
  • 如果子类继承了抽象类,要么子类自身是抽象类,要么实现所有抽象方法
  • 抽象类的目的是规范子类,通常会在比较大型或者规范的项目中才会使用
  • 抽象类中不允许有成员属性
<?php
// 抽象类 abstract

abstract class Human{

    // 普通方法
    public function show(){}

    // 抽象方法,抽象方法存在的类必须是抽象类
    // 抽象方法不能有方法体
    public abstract function eat();
};

// 抽象类不能被实例化
// new Human();

// 继承抽象类的要么为抽象类,要么实现抽象类的所有抽象方法。
class Man extends Human{
    // 实现抽象方法 eat
    public function eat(){}
};
// 可以正常实例化
new Man();

// 抽象子类继承抽象类
abstract class Woman extends Human{
    public abstract function makeup();
}

abstract class Wo extends demo{
    // 实现抽象方法 eat
    public function eat(){}

    // 实现抽象方法 makeup
    public function makeup(){}
}
 // 只有实现了抽象类和继承的抽象类的所有所有抽象方法,才可以实例化
new Wo();

接口是什么

PHP是单继承的,为了解决这个问题,PHP引入了接口。接口是一种特殊的抽象类,而抽象类又是一种特殊的类。

  • 接口不是类,但与类有类似的结构,目的是为了约束类。
  • 接口不能实例化,但类可以实现接口(注意是实现不是继承)
<?php
interface 接口名{}
class 类名 implements 接口名{}    
  • 接口是用来规范项目体系,提供一些必须的行为规范

接口成员: 在接口内部定义的成员

  • 接口成员只允许有两类

    • 接口常量:const
    • public的接口方法(普通方法和静态方法)
  • 接口的方法为抽象方法,没有方法体(不需要abstract 关键字,因为接口方法都是抽象方法)
  • 实现接口的类:

    • 可以访问接口的常量:接口常量不能被重写
    • 需要实现所有的接口方法(除非本身是抽象类)
    • 接口方法实现不允许增加控制权限(必须为 public)
  1. 接口成员:接口中只能定义共有抽象方法和接口常量
<?php
interface Humen{
    // 接口常量
    const NAME = '人';
    // 接口抽象方法
    public function eat();
    public static function show();
}
  1. 接口成员方法必须被实现的子类实现或类为抽象类,接口常量可以直接在实现类中使用
//  实现接口:实体类
class Man implements Humen{
    // 必须实现接口里的所有的抽象方法
    public function eat(){
        // 可以访问常量
       echo self::NAME;
    }
    public static function show(){}
}

// 实现接口:抽象类
abstract class Women implements Humen{};
  1. 类实现接口成员时,不允许重写接口中的常量,不允许增加接口方法的控制权限
class Women implements Humen{
    // 不允许重写接口常量
    const NAME = '小孩';
    // 不允许使用其他访问修饰符,必须使用public
    private function eat();
};

接口继承: 接口可以被接口继承

  • 接口继承接口的目的

    • 实现接口成员的扩展,丰富接口内容,从而实现更好的对实现类的规范
    • 为了形成完整的接口体系,让不同级别的类实现不同级别的接口
  • 接口可以一次性继承多个接口
 interface A{}
 interface B{}
 
 // 接口继承
 interface C extends A{}
 // 接口多继承
 interface D extends A,B{}

总结:

  • 接口可以继承接口,而且是多继承
  • 接口是在大型项目中,为了保证底层的实现而设计的规范,通常是抽象类实现接口,增加必要成员属性,然后让实际业务类去继承抽象类
  • 类在继承其他类的时候可以同时去实现相应的接口,不需要父类和接口有任何关系

接口和抽象的区别

  • 抽象类中可以有非抽象方法,而接口中只能有抽象方法
  • 一个类可以实现多个接口,而一个类只能继承一个抽象方法
  • 接口的使用方式通过 implements实现,而抽象类使用extends 关键字继承。
  • 抽象类中可以声明成员变量,而接口中不能声明成员变量,但可以声明常量。
  • 接口没有构造函数,而抽象类可以有构造函数
  • 接口中的抽象方法只能使用public来修饰,而构造方法可以使用public和protected来修饰
  • 抽象类的抽象方法要使用abstract 来修饰,而接口不需要
Last Modified: September 12, 2021