PHP基礎參考10-類與對象語法


原文:PHP基礎參考10-類與對象語法 - 9ong
PHP基礎參考11-引用語法 - 9ong

很多人都停留在php是過程語言,不能面向對象,php已經(jīng)8了,在5就已經(jīng)逐步與面向對象接軌了姥宝。

PHP 具有完整的對象模型减宣。特性包括: 訪問控制妓雾,抽象類和 final 類與方法摇幻,附加的魔術方法,接口彻犁,對象復制。

對于面向對象的基本知識凰慈,不需要我們介紹了汞幢,大家都懂。

PHP: OOP 變更日志 - Manual

final

被繼承的方法和屬性可以通過用同樣的名字重新聲明被覆蓋微谓。但是如果父類定義方法時使用了 final森篷,則該方法不可被覆蓋〔蛐停可以通過 parent:: 來訪問被覆蓋的方法或屬性仲智。

注意: 屬性不能被定義為 final,只有類和方法才能被定義為 final姻氨。

基本的知識钓辆,但很少人能用上,也許是場景不需要用到,但也許哪天就真香前联,時刻牢記功戚。

var

雖然有些版本允許使用var定義屬性,會被視為public似嗤,但我們不建議使用啸臀。

const常量

常量的值必須是一個定值,不能是變量烁落,類屬性乘粒,數(shù)學運算的結果或函數(shù)調(diào)用。

要區(qū)別于外部const/define定義的常量顽馋。

PHP 7.1.0 開始谓厘,類的常量可以定義為公有、私有或受保護寸谜。如果沒有設置這些關鍵字竟稳,則該常量默認為公有,也就是之前的版本只能使用const關鍵字定義常量熊痴,默認這些常量是公開可訪問的他爸,7.1之后允許public、protect果善、private的訪問控制關鍵字诊笤。

類自動加載

現(xiàn)代php框架都引入自動加載機制了,特別是composer第三方庫使用巾陕。

spl_autoload_register() 函數(shù)可以注冊任意數(shù)量的自動加載器讨跟,當使用尚未被定義的類(class)和接口(interface)時自動去加載。

不建議使用__autoload函數(shù)鄙煤,后續(xù)版本會被棄用晾匠。

spl_autoload_register函數(shù)用于注冊觸發(fā)加載類,提供回調(diào)加載梯刚,達到按需加載凉馆。

spl_autoload_register(function ($class_name) {
    require_once $class_name . '.php';
});

$obj  = new MyClass1();
$obj2 = new MyClass2();

構造函數(shù)與析構函數(shù)

  • 子類的構造函數(shù)不會默認或隱性的調(diào)用父類構造函數(shù),有需要時亡资,要手動調(diào)用父類構造函數(shù)澜共。

  • 析構函數(shù)即使在使用 exit() 終止腳本運行時也會被調(diào)用。但在析構函數(shù)中調(diào)用 exit() 將會中止其余關閉操作的運行锥腻。

  • 在析構函數(shù)(在腳本終止時被調(diào)用)中拋出一個異常會導致致命錯誤嗦董。

范圍解析操作符

范圍解析操作符 ::

只是認識下這個符號叫:范圍解析操作符

在訪問類常量、靜態(tài)屬性瘦黑、靜態(tài)方法展懈,我們常會用到雙冒號销睁,也就是范圍解析操作符。

關于抽象類和接口

如果對抽象類和接口有不清楚的可以看官方文檔介紹

PHP: 抽象類 - Manual

PHP: 對象接口 - Manual

Trait

Trait 是為類似 PHP 的單繼承語言而準備的一種代碼復用機制存崖。Trait 為了減少單繼承語言的限制冻记,使開發(fā)人員能夠自由地在不同層次結構內(nèi)獨立的類中復用 method。

Trait 和 Class 相似来惧,但僅僅旨在用細粒度和一致的方式來組合功能冗栗。 無法通過 trait 自身來實例化。它為傳統(tǒng)繼承增加了水平特性的組合供搀;也就是說隅居,應用的幾個 Class 之間不需要繼承。

  • 優(yōu)先順序是當前類中的方法會覆蓋 trait 方法葛虐,而 trait 方法又覆蓋了基類中的方法胎源。

    
    class Base {
        public function sayHello() {
            echo 'Hello ';
        }
    }
    
    trait HelloWorld {
        public function sayHello() {
            echo 'Hello World!';
        }
    }
    
    class MyHelloWorld extends Base {
        use HelloWorld;
    }
    
    
    $o = new MyHelloWorld();
    $o->sayHello();
    //輸出:Hello World!
    //因為trait覆蓋了基類的方法
    
    class TheWorldIsNotEnough {
        use HelloWorld;
        public function sayHello() {
            echo 'Hello Universe!';
        }
    }    
    
    $o = new TheWorldIsNotEnough();
    $o->sayHello();    
    
    //輸出:Hello Universe!
    //因為當前類覆蓋trait的方法
    
  • 一個類中支持use多個trait,用逗號隔開

  • 方法沖突解決

    如果兩個 trait 都插入了一個同名的方法屿脐,如果沒有明確解決沖突將會產(chǎn)生一個致命錯誤涕蚤。

    為了解決多個 trait 在同一個類中的命名沖突,需要使用 insteadof 操作符來明確指定使用沖突方法中的哪一個的诵。

    以上方式僅允許排除掉其它方法万栅,as 操作符可以 為某個方法引入別名。 注意西疤,as 操作符不會對方法進行重命名烦粒,也不會影響其方法。

    use A, B {
        B::smallTalk insteadof A;//相當于排除A中的smallTalk
        A::bigTalk insteadof B;
        B::bigTalk as talk;//定義了talk別名
    }
    
  • 修改use trait中的方法訪問控制

    直接看范例:

    
    // 修改 sayHello 的訪問控制
    class MyClass1 {
        use HelloWorld { sayHello as protected; }
    }
    
    // 給方法一個改變了訪問控制的別名
    // 原版 sayHello 的訪問控制則沒有發(fā)生變化
    class MyClass2 {
        use HelloWorld { sayHello as private myPrivateHello; }
    }
    
  • trait組合

    trait和class一樣也可以組合其他多個trait代赁。

  • trait支持抽象方法扰她,用于強制實體類實現(xiàn)trait的抽象方法

  • trait支持靜態(tài)方法

  • trait支持屬性,但注意沖突芭碍,一般是不能定義同樣名稱的屬性徒役。我們建議避免trait和class出現(xiàn)相同名稱的屬性,即使訪問可見性豁跑、初始值都一樣(允許的),我也不建議泻云,會導致混亂艇拍。

匿名類

php7開始支持匿名類,用于創(chuàng)建一次性簡單對象宠纯。

$util->setLogger(new class {
    public function log($msg)
    {
        echo $msg;
    }
});
//也就是不需要先定義一個logger的對象卸夕,再new給setLogger方法。

魔術方法

PHP: 魔術方法 - Manual

PHP所提供的重載(overloading)是指動態(tài)地創(chuàng)建類屬性和方法婆瓜。我們是通過魔術方法(magic methods)來實現(xiàn)的快集。

PHP中的重載與其它絕大多數(shù)面向對象語言不同贡羔。傳統(tǒng)的重載是用于提供多個同名的類方法,但各方法的參數(shù)類型和個數(shù)不同个初。

PHP: 重載 - Manual

clone

對象復制可以通過 clone 關鍵字來完成(如果可能乖寒,這將調(diào)用對象的 __clone() 方法)。

當對象被復制后院溺,PHP 5 會對對象的所有屬性執(zhí)行一個淺復制(shallow copy)珍逸。所有的引用屬性 仍然會是一個指向原來的變量的引用叭爱。如果有少量及簡單的引用屬性买雾,可以在魔術方法__clone中手動實現(xiàn)引用屬性的復制缨称。

class AA{
    public $object1;
    function __clone()
    {
    
        // 強制復制一份this->object, 否則仍然指向同一個對象
        $this->object1 = clone $this->object1;
    }
}

$a = new AA();

$a2 = clone $a;//通過__clone方法器净,達到對$a對象的深拷貝当凡。

static::后期靜態(tài)綁定

self沿量、parent朴则、static

我們都知道parent的用法汹想,就是從當前類(子類)往上追溯基類的存在的這個方法古掏;static則是從當前類(父類、基類)往下追溯至當前執(zhí)行實例(子類)中存在的方法侦啸;

class A {
    public static function who() {
        echo __CLASS__;
    }
    public static function test() {
        static::who(); // 后期靜態(tài)綁定從這里開始拧烦,這里會執(zhí)行調(diào)用test方法的實例的who方法,也就是B類實例的who方法。
        self::who();//這里只會調(diào)用當前類中的who方法秦士,如果有的話,也就是當前代碼行所在類A
        parent::who();
    }
}

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

B::test();//輸出:BA

對象與引用及傳址賦值與引用賦值

在php5 的對象編程經(jīng)常提到的一個關鍵點是“默認情況下對象是通過引用傳遞的”隧土。但其實這不是完全正確的。

PHP 的引用是別名艇抠,就是兩個不同的變量名字指向相同的內(nèi)容。

在 PHP 5以后异剥,一個對象變量已經(jīng)不再保存整個對象的值青伤。而是保存一個標識符來訪問真正的對象內(nèi)容擎厢。

當對象作為參數(shù)傳遞,作為結果返回厘惦,或者賦值給另外一個變量偷仿,另外一個變量跟原來的不是引用的關系,只是他們都保存著同一個標識符的拷貝宵蕉,這個標識符指向同一個對象的真正內(nèi)容酝静。

這標識符我們可以理解為存儲地址,所以php的對象正常情況下的復制羡玛、傳遞都是通過傳址的方式别智,而不是引用,雖然效果是一樣的稼稿。

class A {
    public $foo = 1;
}  

$a = new A;
$b = $a;     // $a ,$b都是同一個標識符的拷貝薄榛,意味著a、b指向同一個地址
            // ($a) = ($b) = <id>
$b->foo = 2;
echo $a->foo."\n";//輸出:2


$c = new A;
$d = &$c;    // $c ,$d是引用让歼,d是c的一個別名敞恋,其實他們還是一樣的
            // ($c,$d) = <id>

$d->foo = 2;
echo $c->foo."\n";//輸出:2


$e = new A;

function foo($obj) {//e和obj都是同一個標識符的拷貝
    // ($obj) = ($e) = <id>
    $obj->foo = 2;
}

foo($e);
echo $e->foo."\n";//輸出:2

原文:PHP基礎參考10-類與對象語法 - 9ong
PHP基礎參考11-引用語法 - 9ong

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
禁止轉載,如需轉載請通過簡信或評論聯(lián)系作者谋右。
  • 序言:七十年代末硬猫,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子倚评,更是在濱河造成了極大的恐慌浦徊,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件天梧,死亡現(xiàn)場離奇詭異盔性,居然都是意外死亡,警方通過查閱死者的電腦和手機呢岗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門冕香,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人后豫,你說我怎么就攤上這事悉尾。” “怎么了挫酿?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵构眯,是天一觀的道長。 經(jīng)常有香客問我早龟,道長惫霸,這世上最難降的妖魔是什么猫缭? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮壹店,結果婚禮上猜丹,老公的妹妹穿的比我還像新娘。我一直安慰自己硅卢,他們只是感情好射窒,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著将塑,像睡著了一般脉顿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上点寥,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天弊予,我揣著相機與錄音,去河邊找鬼开财。 笑死汉柒,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的责鳍。 我是一名探鬼主播碾褂,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼历葛!你這毒婦竟也來了正塌?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤恤溶,失蹤者是張志新(化名)和其女友劉穎乓诽,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體咒程,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡鸠天,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了帐姻。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片稠集。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖饥瓷,靈堂內(nèi)的尸體忽然破棺而出剥纷,到底是詐尸還是另有隱情,我是刑警寧澤呢铆,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布晦鞋,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏悠垛。R本人自食惡果不足惜吼砂,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鼎文。 院中可真熱鬧,春花似錦因俐、人聲如沸拇惋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽撑帖。三九已至,卻和暖如春澳眷,著一層夾襖步出監(jiān)牢的瞬間胡嘿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工钳踊, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留衷敌,地道東北人。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓拓瞪,卻偏偏與公主長得像缴罗,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子祭埂,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容