PHP 手冊 (類與物件) 學習筆記一:基本概念

小彭友發表於2020-05-26

關鍵詞:class
定義:每個類的定義都以關鍵字 class 開頭,後面跟著類名,後面跟著一對花括號,裡面包含有類的屬性與方法的定義
規則:類名可以是任何非 PHP 保留字的合法標籤。一個合法類名以字母或下劃線開頭,後面跟著若干字母,數字或下劃線
包含:一個類可以包含有屬於自己的常量,變數(稱為“屬性”)以及函式(稱為“方法”)
Example 1:簡單的類定義

<?php
   class SimpleClass
   {
       public $var = 'a default value';

       public function displayVar()
       {
           echo $this->var;
       }
   }
?>

備註:當一個方法在類定義內部被呼叫時,有一個可用的偽變數 $this。$this 是一個到主叫物件的引用(通常是該方法所從屬的物件,但如果是從第二個物件靜態呼叫時也可能是另一個物件)
Example 2:偽變數的示例

   class A
   {
       function foo()
       {
           if(isset($this)) {
                echo "\$this is defined (";
                echo get_class($this);
                echo ")\n";
           } else {
                echo "\$this is not defined.\n";
           }
       }
   }

   class B
   {
       function bar()
       {
           A::foo();
       }
   }

   $a = new A();
   $a->foo();//$this is defined (A)
    A::foo();//$this is not defined
    $b = new B();
    $b->bar();//PHP 5.6: $this is defined (B) PHP 7:$this is not defined(沒有測試過)
    B::bar();//$this is defined (B)

關鍵詞:new
概念:要建立一個類的例項,必須使用 new 關鍵字。當建立新物件時該物件總是被賦值,除非該物件定義了建構函式並且在出錯時丟擲了一個異常。類應在被例項化之前定義(某些情況下則必須這樣)。

如果在 new 之後跟著的是一個包含有類名的字串 string,則該類的一個例項被建立。如果該類屬於一個名稱空間,則必須使用其完整名稱。
Example 3:建立例項

   class SimpleClass
   {
       public $var = 'a default value';

       public function displayVar()
       {
           echo $this->var;
       }
   }

   $instance = new SimpleClass();

   //也可以:
    $className = 'SimpleClass';
    $instance = new $className;

在類定義內部,可以用 new self 和 new parent 建立新物件。
當把一個物件已經建立的例項賦給一個新變數時,新變數會訪問同一個例項,就和用該物件賦值一樣。此行為和給函式傳遞入例項時一樣。可以用克隆給一個已建立的物件建立一個新例項。
Example 4:物件賦值

  class SimpleClass
   {
       public $var = 'a default value';

       public function displayVar()
       {
           echo $this->var;
       }
   }

   $instance = new SimpleClass();
   $assigned = $instance;
   $reference = & $instance;
   $instance->var = '$assigned will have this value';
   $instance = null;
   var_dump($instance);//NULL
   var_dump($assigned);
   /*object(SimpleClass)#1 (1) {
["var"]=>
     string(30) "$assigned will have this value"
}*/
   var_dump($reference);//NULL

Example 5:建立新物件

  class Test
    {
        static public function getNew()
        {
            return new static;
        }
    }

    class Child extends Test
    {}
    $obj1 = new Test();
    $obj2 = new $obj1;
    var_dump($obj1 !== $obj2);//bool(true)
    $obj3 = Test::getNew();
    var_dump($obj3 instanceof Test);//bool(true)
    $obj4 = Child::getNew();
    var_dump($obj4 instanceof Child);//bool(true)
    var_dump($obj4 instanceof Test);//bool(true)

Example 6:訪問新建立物件的成員

echo (new DateTime())->format('Y');//2020

關鍵詞:屬性和方法
Example 7:屬性名和方法的呼叫

   class Foo
    {
        public $bar = 'property';

        public function bar()
        {
            return 'method';
        }
    }
    $obj = new Foo();
    echo $obj->bar, PHP_EOL, $obj->bar(), PHP_EOL;
    /*
    property
    method
    */

Example 7:屬性裡儲存匿名函式

class Foo1
    {
        public $bar;
        public function __construct()
        {
            $this->bar = function(){
                return 42;
            };
        }
    }

    $obj = new Foo1;
    $func = $obj->bar;
    echo $func(), PHP_EOL;//42
    echo ($obj->bar)(), PHP_EOL;//PHP 5.6執行報錯,PHP7可以(沒試過)

關鍵詞:extends
一個類可以在宣告中用 extends 關鍵字繼承另一個類的方法和屬性。PHP不支援多重繼承,一個類只能繼承一個基類

被繼承的方法和屬性可以通過用同樣的名字重新宣告被覆蓋。但是如果父類定義方法時使用了 final,則該方法不可被覆蓋。可以通過 parent:: 來訪問被覆蓋的方法或屬性。

當覆蓋方法時,引數必須保持一致否則 PHP 將發出 E_STRICT 級別的錯誤資訊。但建構函式例外,建構函式可在被覆蓋時使用不同的引數。
Example 9:簡單的類繼承

   class SimpleClass
   {
       public $var = 'a default value';

       public function displayVar()
       {
           echo $this->var;
       }
   }


    class ExtendClass extends SimpleClass
    {
        public function displayVar()
        {
            echo "Extending class\n";
            parent::displayVar();
        }
    }

    $extended = new ExtendClass();
    $extended->displayVar();
    /*
    Extending class
    a default value
    */

關鍵詞:::class
自 PHP 5.5 起,關鍵詞 class 也可用於類名的解析。使用 ClassName::class 你可以獲取一個字串,包含了類 ClassName 的完全限定名稱。這對使用了 名稱空間 的類尤其有用。
Example 10:類名的解析

    namespace NS {
        class ClassName
        {}
        echo ClassName::class, PHP_EOL;//NS\ClassName
    }

補充:get_class()和get_called_class()的區別

class Foo{
    public function test(){
        var_dump(get_class());
    }

    public function test2(){
        var_dump(get_called_class());
    }

    public static function test3(){
        var_dump(get_class());
    }

    public static function test4(){
        var_dump(get_called_class());
    }
}

class B extends Foo
{}

$foo = new Foo();
$foo->test();//string(3) "Foo"
$foo->test2();//string(3) "Foo"

$B = new B();
$B->test();//string(3) "Foo"
$B->test2();//string(3) "B"

Foo::test3();//string(3) "Foo"
Foo::test4();//string(3) "Foo"

B::test3();//string(3) "Foo"
B::test4();//string(3) "B"

get_class (): 獲取當前呼叫方法的類名;
get_called_class():獲取靜態繫結後的類名;
附原文手冊連線:本文程式碼全部手敲驗證

PHP手冊(類與物件)學習筆記一:基本概念

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章