• PHP 中的关于 trait 的简单


    什么是 trait

      看看 PHP 官网的介绍。

    自 PHP 5.4.0 起,PHP 实现了一种代码复用的方法,称为 trait。

    Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制。Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用 method。Trait 和 Class 组合的语义定义了一种减少复杂性的方式,避免传统多继承和 Mixin 类相关典型问题。

    Trait 和 Class 相似,但仅仅旨在用细粒度和一致的方式来组合功能。 无法通过 trait 自身来实例化。它为传统继承增加了水平特性的组合;也就是说,应用的几个 Class 之间不需要继承。

    例子1

      手机和汽车都有 GPS 功能,GPS 是用来定位的功能的,因此功能应该是统一的。手机 和 汽车 除了 GPS 功能外,基本没有什么相同之处,因此不能使用继承。而接口的话,我认为不同的类去实现接口时,接口的实现可能是不同的,但是 GPS 的功能就是用来定位的。因此使用 trait ,而不使用 class 和 interface,这是我的理解,不知道是否正确。

      gps.php 的定义:

    1 <?php
    2 
    3 trait Gps {
    4     public function gps() {
    5         echo 'i can gps';
    6     }
    7 }

      使用 trait 定义了一个 GPS 的 trait 用于复用,它的关键字是 trait 。然后在 car.php 和 mobile.php 中进行引用。

      

      car.php 的定义:

    1 class Car {
    2     use gps;
    3 
    4     public function move() {
    5         echo 'i can move';
    6     }
    7 }

      mobile.php 的定义:

    1 <?php
    2 
    3 class Mobile {
    4     use gps;
    5     public function tel() {
    6         echo 'i can tel';
    7     }
    8 }

      在 car.php 和 mobile.php 中,使用 use 关键字引入了 gps 的 trait ,这样在 car 和 mobile 中就可以调用 gps() 这个方法了。

      test.php 进行测试:

     1 <?php
     2 
     3 require_once('gps.php');
     4 require_once('car.php');
     5 require_once('mobile.php');
     6 
     7 $car = new Car();
     8 $mobile = new Mobile();
     9 
    10 $car->gps();
    11 echo "
    ";
    12 $mobile->gps();

      输出结果如下:

    1 i can gps
    2 i can gps

    例子2

      在 car 中引入了另外一个国产的 gps 。

      gpschina.php 定义如下:

    1 <?php
    2 
    3 trait GpsChina {
    4 
    5     public function gps() {
    6         echo 'i can chinae gps';
    7     }
    8 }

      在 car 中引入,修改 car.php 的定义如下:

     1 <?php
     2 
     3 
     4 class Car {
     5     use gps, gpschina;    
     6 
     7     public function move() {
     8         echo 'i can move';
     9     }
    10 }

      再次调用 test.php 进行测试,这时会报错,报错如下:

    1 Fatal error: Trait method gps has not been applied, because there are collisions with other trait methods on Car in Car.php on line 4

      因为在引入的 trait 中 gps 和 gpschina 各有一个 gps ,而直接使用 $car->gps() 时无法确定到底使用的是 gps 的 gps() 方法,还是使用的 gpschina 的 gps() 方法,因此报错了。这样的话,我们需要确定一个。修改 car.php 文件。

     1 <?php
     2 
     3 class Car {
     4     use gps, gpschina {
     5         GpsChina::gps insteadof Gps;
     6     }
     7     
     8     public function move() {
     9         echo 'i can move';
    10     }
    11 }

      这样就使用 GpsChina::gps 的方法 替换掉了 Gps 的方法了,在调用 test.php 进行查看。

    1 i can chinae gps
    2 i can gps

      这样,对于 $car->gps() 后就调用了 gpschina 中的 gps() 方法了。

    例子3

      如果在 Car 类中本身有一个 gps() 方法呢?修改 Car 类。

     1 <?php
     2 
     3 class Car {
     4     use gps, gpschina {
     5         GpsChina::gps insteadof Gps;
     6     }
     7     
     8     public function gps() {
     9         echo 'car::gps';
    10     }
    11     
    12 
    13     public function move() {
    14         echo 'i can move';
    15     }
    16 }

      调用 test.php 查看结果:

    1 car::gps
    2 i can gps

      可以看出,调用了 Car 类本身的 gps() 方法。

      

      如果在一个类中,继承自父类的方法、use 引入 trait 的方法 和 类自身的方法同名的话,优先调用 自身类的 方法,如果没有 自身类的方法 则调用 use 引入 trait 的方法,如果前两个都没有,那么就调用继承自父类的方法。

      

      关于 trait 更多的用法,请参考:http://www.php.net/manual/zh/language.oop5.traits.php


    我的微信公众号:“码农UP2U”

  • 相关阅读:
    图像滤波
    直方图histeq
    直方图
    基于灰度变换的图像增强
    图像增强
    图像旋转和缩放
    图像点运算
    像素的连接与联通
    程序员进阶之算法练习(一)
    RxSwift 系列(二)
  • 原文地址:https://www.cnblogs.com/tosser/p/9637732.html
Copyright © 2020-2023  润新知