天天看點

速戰速決 (4) - PHP: 類基礎, 抽象類, 接口, trait

速戰速決 之 PHP: 類基礎, 抽象類, 接口, trait

[源碼下載下傳]

速戰速決 (4) - PHP: 類基礎, 抽象類, 接口, trait

作者:webabcd

介紹

速戰速決 之 PHP

  • 類基礎
  • 抽象類
  • 接口
  • trait

示例

1、類的相關知識點 1(基礎)

class/class1.php

<?php
/**
 * 類的相關知識點 1(基礎)
 *
 * 規範:命名空間與目錄路徑對應,類名與檔案名對應,檔案以 .class.php 為字尾名
 */

class MyClass1
{
    // 類常量,沒有“$”符号,不能被覆寫
    const MyConstant = 'constant value';
    // 靜态屬性
    static $myStaticProperty = "static property";

    // 對于屬性和方法的通路控制有 private protected public(預設值)
    private $_name;
    private $_age;

    // 構造函數
    // PHP 中的魔術方法(magic method)均以 __(兩個下劃線)開頭(類似的還有 __destruct(),__call(),__callStatic(),__get(),__set(),__isset(),__unset(),__sleep(),__wakeup(),__toString(),__invoke(),__set_state() 和 __clone() 等)
    function __construct()
    {
        echo "MyClass1 construct";
        echo "<br />";

        // 擷取參數個數
        $args_num = func_num_args();

        if ($args_num == 1)
        {
            // $this 代表目前對象,是指向類執行個體的指針
            $this->_name = func_get_arg(0);
        }
        else if ($args_num == 2)
        {
            $this->_name = func_get_arg(0);
            $this->_age = func_get_arg(1);
        }
        else
        {

        }
    }

    // 析構函數
    function __destruct()
    {
        print "MyClass1 destruct";
        echo "<br />";
    }

    // 構造函數,此種方式在 PHP 5.3.3 或以上可支援
    // 此種方式的構造函數也可以當做方法被調用
    public function MyClass1()
    {
        echo "i am not a construct, i am a method";
    }

    // 靜态方法
    public static function myStaticMethod()
    {
        return "static method";
    }

    // 方法
    public function getInfo()
    {
        // $this 代表目前對象,是指向類執行個體的指針
        return "name: " . $this->_name . ", age: " . $this->_age;
    }

    // 不直接支援方法的重載(overload),可以通過相關的魔術方法來實作(參見:class3.php)
    // public function getInfo($name) { }

    // 帶參數類型限制的方法,類型限制不能用于 int 或 string 之類的标量類型
    // 本例限制了參數 $ary 必須是 array 類型
    public function getFirst(array $ary)
    {
        return $ary[0];
    }
}

// 被聲明為 final 的類或屬性或方法,無法繼承
// 隻能繼承一個類
final class MyClass2 extends MyClass1
{
    // 構造函數可以為參數設定預設值(方法或函數也可以為參數設定預設值)
    function __construct($name = "wanglei", $age = 100)
    {
        echo "MyClass2 construct";
        echo "<br />";

        // parent 代表目前類的基類
        parent::__construct($name, $age);

        // self 代表目前類
        // $this 代表目前對象,是指向類執行個體的指針
    }

    // 析構函數
    function __destruct()
    {
        print "MyClass2 destruct";
        echo "<br />";

        parent::__destruct();
    }

    // 覆寫基類的同名方法(override)
    public function getInfo()
    {
        // $this 代表目前對象,指向類執行個體的指針
        return "MyClass2 - " . parent::getInfo();
    }
}

// 類的執行個體化
$objClass1 = new MyClass1("webabcd", 35);
// 通過 -> 調用執行個體方法或執行個體屬性
echo $objClass1->getInfo();
echo "<br />";
// 通過 -> 調用執行個體方法或執行個體屬性(MyClass1() 是構造函數,也可以當做方法被調用)
echo $objClass1->MyClass1();
echo "<br />";

$objClass2 = new MyClass2();
echo $objClass2->getInfo();
echo "<br />";

// instanceof - 用于判斷一個對象是否是指定類的執行個體
if($objClass2 instanceof MyClass1)
{
    echo '$objClass2 instanceof MyClass1';
    echo "<br />";
}

// 通過 :: 調用類常量或靜态屬性或靜态方法
echo MyClass1::MyConstant;
echo "<br />";

// 通過 :: 調用類常量或靜态屬性或靜态方法
echo MyClass1::$myStaticProperty;
echo "<br />";

// variable class(可變類),将變量的值作為類名
$className = 'MyClass1';
// variable method(可變方法),将變量的值作為方法名
$methodName = 'myStaticMethod';
// 通過 :: 調用類常量或靜态屬性或靜态方法
echo $className::$methodName();
echo "<br />";

// 調用帶參數類型限制的方法
echo $objClass1->getFirst(array("a", "b", "c"));
echo "<br />";      

2、類的相關知識點 2(抽象類,接口,trait)

class/class2.php

<?php
/**
 * 類的相關知識點 2(抽象類,接口,trait)
 */

// 抽象類
abstract class MyAbstractClass
{
    // 抽象方法,子類必須定義這些方法
    abstract protected function getValue1();
    abstract public function getValue2($param1);

    // 普通方法(非抽象方法)
    public function getValue0()
    {
        return "getValue0";
    }
}

// 接口
interface MyInterface1
{
    // 接口常量,不能被覆寫
    const MyConstant = 'constant value';
    public function getValue3();
}

// 接口
interface MyInterface2 extends MyInterface1
{
    public function getValue4();
}

// 接口
interface MyInterface3
{
    public function getValue5();
}

// trait(可以 use 多個,允許有實作代碼,但是本身不能執行個體化)
trait MyTrait1
{
    // 可以具有方法,靜态方法,屬性等
    function getValue6()
    {
        return "getValue6";
    }
}

// trait(可以 use 多個,允許有實作代碼,但是本身不能執行個體化)
trait MyTrait2
{
    // 抽象方法(use 這個 trait 的類必須要定義這個方法)
    abstract function getValue7();
}

// trait(可以 use 多個,允許有實作代碼,但是本身不能執行個體化)
trait MyTrait3
{
    function getValue6()
    {
        return "getValue6";
    }

    function getValue8()
    {
        return "getValue8";
    }
}

// 必須實作所有抽象方法和接口方法
// 類隻能單繼承,接口可以多繼承
class MyClass1 extends MyAbstractClass implements MyInterface2, MyInterface3
{
    // 可以 use 多個 trait
    use MyTrait1, MyTrait2;
    use MyTrait3
    {
        // 多 trait 間有重名的,可以指定以哪個為準
        MyTrait1::getValue6 insteadof MyTrait3;
        // 可以為 trait 的指定方法設定别名(調用的時候用方法名也行,用别名也行)
        MyTrait3::getValue8 as alias;
    }

    // 可以将 protected 更新為 public
    public function getValue1()
    {
        return "getValue1";
    }

    // 可以加參數,但是加的參數必須要有預設值
    public function getValue2($param1, $param2 = 'param2')
    {
        return "getValue2, {$param1}, {$param2}";
    }

    public function getValue3()
    {
        return "getValue3";
    }

    public function getValue4()
    {
        return "getValue4";
    }

    public function getValue5()
    {
        return "getValue5";
    }

    public function getValue7()
    {
        return "getValue7";
    }
}

// 調用接口常量
echo MyInterface1::MyConstant;
echo "<br />";

$myClass1 = new MyClass1;
echo $myClass1->getValue0();
echo "<br />";
echo $myClass1->getValue1();
echo "<br />";
echo $myClass1->getValue2("webabcd");
echo "<br />";
echo $myClass1->getValue3();
echo "<br />";
echo $myClass1->getValue4();
echo "<br />";
echo $myClass1->getValue5();
echo "<br />";
echo $myClass1->getValue6();
echo "<br />";
echo $myClass1->getValue7();
echo "<br />";
echo $myClass1->getValue8();
echo "<br />";
echo $myClass1->alias();
echo "<br />";      

OK