zoukankan      html  css  js  c++  java
  • 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关键字导入,可是导入的位置有所不同。命名空间,类,接口,函数和常量在类的定义体外导入。
        而性状在类的定义体内导入。

        

        

  • 相关阅读:
    docker重启提示已存在一个容器的问题处理
    conda虚拟环境安装
    dell5460笔记本电脑ubuntu18.04系统音频驱动的安装和使用
    CentOS8的网络管理变化
    jupyter notebook 安装扩展nbextensions
    win10系统systeminfo命令的过滤用法
    《学习scrapy框架爬小说》的进一步完善
    记手机端 下拉加载新数据
    记 页面使用overflow-scroll在iOS上滑动卡顿的问题
    记 判断手机号运营商function
  • 原文地址:https://www.cnblogs.com/wmzll/p/13177674.html
Copyright © 2011-2022 走看看