类与对象的学习(一)

一、trait

http://php.net/manual/zh/language.oop5.traits.php

应用的几个 Class 之间不需要继承

自己的理解 trait 不需要去继承 指需在需要用到它的类里面 use 其名称即可,同时须在 class 上方use 完整地址如下

<?php

namespace app\customer\model;

use app\manager\model\Staff;
use app\oa\relation\Commentable;
use think\Model;
use think\model\concern\SoftDelete;

/**
 * @property integer $id
 */
class Reimbursement extends Model
{
    use SoftDelete,Commentable;

    const SUCCESS = 654;    //已完成
    const PENDING = 655;    //待处理
    const PROCESSING = 661; //处理中
    const CHECK = 662;      //待审核
    const SETTLED = 663;    //待结算
    const DISMISSED = 664;  //已驳回
    const REJECT = 690;     //已拒绝
    protected $name = 'reimbursement';

    protected $type = [
        'album' => 'json',
        'payment_pic' => 'json',
        'reimbursement' => 'json'
    ];

    /**
     * @param array $data 新增
     * @return false|int
     */
    public function store($data)
    {
        return $this->isUpdate(false)->allowField(true)->save($data);
    }

    /**
    * @param array $data 修改
    * @return false|int
    */
    public function edit($data)
    {
        return $this->isUpdate(true)->allowField(true)->save($data);
    }

    public function results()
    {
        return $this->hasOne(ReimbursementResult::class,'reimbursement_id');
    }

    public function staffs()
    {
        return $this->hasOne(Staff::class,'id','staff_id')->field('id,real_name');
    }

    public function getTypeAttr($raw)
    {
        $segments = explode(',', $raw);
        $result = [];
        foreach ($segments as $segment) {
            $result[] = ['id' => $segment, 'dictionary_name' =>array_get(app('dict'), $segment)];
        }
        return $result;
    }
}

从基类继承的成员会被 trait 插入的成员所覆盖。优先顺序是来自当前类的成员覆盖了 trait 的方法,而 trait 则覆盖了被继承的方法。

abstract 

http://php.net/manual/zh/language.oop5.abstract.php

抽象类【定义为抽象的类不能被实例化,如果一个类里面有抽象方法,那么这个类就必须声明为抽象类,被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现。】

<?php
abstract class AbstractClass
{
 // 强制要求子类定义这些方法
    abstract protected function getValue();
    abstract protected function prefixValue($prefix);

    // 普通方法(非抽象方法)
    public function printOut() {
        print $this->getValue() . "\n";
    }
}

class ConcreteClass1 extends AbstractClass
{
    protected function getValue() {
        return "ConcreteClass1";
    }

    public function prefixValue($prefix) {
        return "{$prefix}ConcreteClass1";
    }
}

class ConcreteClass2 extends AbstractClass
{
    public function getValue() {
        return "ConcreteClass2";
    }

    public function prefixValue($prefix) {
        return "{$prefix}ConcreteClass2";
    }
}

$class1 = new ConcreteClass1;
$class1->printOut();
echo $class1->prefixValue('FOO_') ."\n";

$class2 = new ConcreteClass2;
$class2->printOut();
echo $class2->prefixValue('FOO_') ."\n";
?>

返回数据

ConcreteClass1
FOO_ConcreteClass1
ConcreteClass2
FOO_ConcreteClass2

对象接口

interface 【使用接口(interface),可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容,接口是通过 interface 关键字来定义的,就像定义一个标准的类一样,但其中定义所有的方法都是空的。接口中定义的所有方法都必须是公有,这是接口的特性。】

implements 【实现接口】【实现多个接口时,接口中的方法不能有重名、接口也可以继承,通过使用 extends 操作符、类要实现接口,必须使用和接口中所定义的方法完全一致的方式。否则会导致致命错误。】

Final 关键字

新增了一个 final 关键字。如果父类中的方法被声明为 final,则子类无法覆盖该方法。如果一个类被声明为 final,则不能被继承。

异常处理

<?php
function inverse($x) {
    if (!$x) {
        throw new Exception('Division by zero.');
    }
    return 1/$x;
}

try {
    echo inverse(5) . "\n";
    echo inverse(0) . "\n";
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}

// Continue execution
echo "Hello World\n";
?>

返回数据

0.2
Caught exception: Division by zero.
Hello World

finally 的异常处理

<?php
function inverse($x) {
    if (!$x) {
        throw new Exception('Division by zero.');
    }
    return 1/$x;
}

try {
    echo inverse(5) . "\n";
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
} finally {
    echo "First finally.\n";
}

try {
    echo inverse(0) . "\n";
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
} finally {
    echo "Second finally.\n";
}

// Continue execution
echo "Hello World\n";
?>

返回数据

0.2
First finally.
Caught exception: Division by zero.
Second finally.
Hello World

抛出异常

<?php

class MyException extends Exception { }

class Test {
    public function testing() {
        try {
            try {
                throw new MyException('foo!');
            } catch (MyException $e) {
                // rethrow it
                throw $e;
            }
        } catch (Exception $e) {
            var_dump($e->getMessage());
        }
    }
}

$foo = new Test;
$foo->testing();

?>

以上会输出

string(4) "foo!"

static 【后期静态绑定】 self 【当前调用】

http://php.net/manual/zh/language.oop5.late-static-bindings.php

self:: 的限制 

使用 self:: 或者 __CLASS__ 对当前类的静态引用,取决于定义当前方法所在的类:

self:: 用法

<?php
class A {
    public static function who() {
        echo __CLASS__;
    }
    public static function test() {
        self::who();
    }
}

class B extends A {
    public static function who() {
        echo __CLASS__;
    }
}

B::test();
?>

以上会输出

A

static:: 简单用法

<?php
class A {
    public static function who() {
        echo __CLASS__;
    }
    public static function test() {
        static::who(); // 后期静态绑定从这里开始
    }
}

class B extends A {
    public static function who() {
        echo __CLASS__;
    }
}

B::test();
?>

以上会输出

B

后期静态绑定的解析会一直到取得一个完全解析了的静态调用为止。另一方面,如果静态调用使用 parent:: 或者 self:: 将转发调用信息。

<?php
class A {
    public static function foo() {
        static::who();
    }

    public static function who() {
        echo __CLASS__."\n";
    }
}

class B extends A {
    public static function test() {
        A::foo();
        parent::foo();
        self::foo();
    }

    public static function who() {
        echo __CLASS__."\n";
    }
}
class C extends B {
    public static function who() {
        echo __CLASS__."\n";
    }
}

C::test();
?>

以上会输出 

A

C

C

猜你喜欢

转载自blog.csdn.net/Json159/article/details/82708363
今日推荐