Fuzqing

PHP接口和抽象类
PHP接口(interface)和抽象类(abstract)对象接口 ¶使用接口(interface),可以指定某...
扫描右侧二维码阅读全文
29
2019/04

PHP接口和抽象类

PHP接口(interface)和抽象类(abstract)

对象接口

使用接口(interface),可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容。

抽象类

PHP 5 支持抽象类和抽象方法。定义为抽象的类不能被实例化。任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现。

两者看起来很相似,那什么时候用接口什么时候用抽象类呢?

什么时候用接口?

其实PHP的官方说明已经说得很清楚了,接口可以指定某个类必须实现哪些方法。

比如定义一个商品接口,各个商品类都需要继承此接口,因为需要在前台统一使用getList()方法来获取商品列表,使用getChild($prod_id,$prod_type)来获取商品详情。

<?php
// 声明一个'IProduct'接口
interface IProduct
{
    // 获取商品列表
    public function getList();
    // 获取单个商品详情
    public function getChild($prod_id,$prod_type);
}

什么时候用抽象类呢?

读取一个商品仅仅是根据商品ID从数据库读取吗?
实际上我们可能还需要同时执行如下操作:

  1. 增加该商品的当日点击量
  2. 增加用户商品浏览记录
  3. 设置一些系统日志等等

为了实现以上1,2,3等等的操作步骤,我们要引入一个模板模式:

  1. 定义一个多步方法的基本骨架
  2. 子类中如果有多个公共行为,可以集中到一个模板方法中
  3. 方便后续的统一修改和维护

这个时候就可以使用抽象类了。

 // 声明一个专门处理加载数据行为的抽象类
abstract class ProdLoadTemplate
{
    public function loadData($prod_id,$prod_type)
    {
        $this->setXX();
        $this->setClick($prod_id);
        $this->setLog($prod_id);
        //执行数据库方法, 根据 $prod_type 不同,返回不同数据(拼凑不同的SQL)
        return new class($prod_id,$prod_type){
            function __construct($prod_id,$prod_type)
            {
                //假设这是从数据库取内容
                $arr=["prod_id"=>103,"prod_name"=>"黑客技术从入门到入狱"];
                foreach($arr as $k=>$v) {
                    $this->$k=$v;
                }   
            }
        };
    }
    // 代表设置点击量
    abstract public function setClick($prod_id);
    // 设置日志
    abstract public function setLog($prod_id);
    // 写上具体通用方法
    public function setXX()
    {
        echo "通用设置方法<hr/>";
    }
}
<?php
// 具体商品类的实现
class Books extends ProdLoadTemplate  implements IProduct
{
    public function getChild($prod_id)
    {
         return parent::loadData($prod_id,"Books");
    }
    
    public function getList()
    {
        return [
            ["prod_id"=>101,"prod_name"=>"java从入门到住院"],
            ["prod_id"=>102,"prod_name"=>"php从精通到放弃"],
            ["prod_id"=>103,"prod_name"=>"黑客技术从入门到入狱"],
            ["prod_id"=>104,"prod_name"=>"python光速入门"],
            ["prod_id"=>105,"prod_name"=>"三小时学会golang"],
        ];
    }
   
    public function setClick($prod_id)
    {
        echo "图书点击量设置<hr/>";
    }

    public function setLog($prod_id)
    {
        echo "图书日志设置<hr/>";
    }
}

总结

当我们需要子类必须实现某些指定方法且不需要按照我们的指定的方式调用的时候就可以用接口。

当我们需要实现多个步骤的操作而某些子类又不需要操作某些步骤的时候,就可以使用抽象类。

Last modification:May 22nd, 2019 at 11:54 am
If you think my article is useful to you, please feel free to appreciate

Leave a Comment