PHP 性状

  什么是性状?

  性状是在PHP5.4.0引入的新概念,既像类又像接口。

  性状是类的部分实现(即常量,属性和方法),可以混入一个或多个现有的PHP类中。

  作用:

    1. 表明类可以做什么(像是接口)

    2. 提供模块化实现(像是类)

  

  PHP是一种面向对象语言,使用的是典型的继承模型。在继承模型中,我们通过先编写一个通用的根类,实现基本功能,然后扩展这个类,创建更具体的类,从直接父类继承实现。  

  

  为什么使用性状(也就是性状产生的原因)?

    

    在大多数时候,通过使用继承就可以解决大部分的问题。但是,如果让两个毫不相关的类具有类似的行为,应该怎么做呢?

    例如:

      现在有两个类,一个是汽车类(Car)和手机类(Phone)。

      这两个类的作用十分不同,而且在继承层次结构关系中没有共同的父类。

      不过,这两个类都应该能使用地理位置(GPS)技术转换成经纬度,然后显示在地图上。

    

    性状就是为了解决这种问题而诞生的。性状能把模块化的实现方式注入多个无关的类中。而且性状还能够促进代码重用。

    

    为了解决上述,第一反应,就是通过编一个GPS基类,让汽车类(Car)和手机类(Phone)都继承GPS类。

    但是,这种做法非常不好,强制让两个毫不相关的类继承同一个父类(祖先)。

    第二反应,创建一个GPS接口,定义实现地理位置功能需要的方法,然后让汽车类和手机类都实现这个接口,这种做法比较好的地方,是每个类都能保持原有的继承结构。

    但是,违反了DRY原则,需要在每个实现类中写入相同的与地理位置相关功能的代码。

    接下来,可以通过性状来实现上述问题。

    

// 创建GPS性状
trait GPS {
    protected $address;
    
    protected $geocoderResult;
    
    public function setAddress($address)
    {
        $this->address = $address;
    }
    
    public function getLatitude()
    {
        if (isset($this->geocoderResult) === false) {
            $this->geocodeAddress();
        }
    }
    
    public function geocodeAddress()
    {
        $this->geocoderResult = $this->geocoder->geocode($this->address);
    }
    
    public function getLongitude()
    {
        if (isset($this->geocoderResult) === false) {
            return $this->geocodeAddress();
        }
        
        return $this->geocoderResult->getLongitude();
    }
}

    GPS性状中,只实现与地理位置相关的功能,除此之外什么都不需要。

 

// 性状的使用
class Car 
{
    use GPS;
    // TODO 类的具体实现       
}   

class Phone
{
    use GPS;
    // TODO 类的具体实现    
}


建议:命名空间和性状都使用use关键字导入,可是导入的位置有所不同。命名空间,类,接口,函数和常量在类的定义体外导入。
    而性状在类的定义体内导入。

    

    

原文地址:https://www.cnblogs.com/wmzll/p/13177674.html