詳解php中的類與對象(繼承)
簡介
在php中,類型的繼承使用extends關鍵字,而且最多只能繼承一個父類,php不支持多繼承。
class MyClass { public $dat = 0; public function __construct($dat) { $this->dat = $dat; } public function getDat() { return "$this->dat\n"; } } class MySubClass extends MyClass { public function getDat() { return "dat: $this->dat\n"; } } $a = new MyClass(3); $b = new MySubClass(4); echo $a->getDat(); // 3 echo $b->getDat(); // dat: 4
方法覆蓋
包括構造函數(shù)在內,子類可以重新定義同名的類方法以覆蓋父類方法。覆蓋時遵循以下規(guī)則:
1.除構造函數(shù)之外,其他函數(shù)在覆蓋時,函數(shù)的參數(shù)列表必須相同
2.包括構造函數(shù)在內,方法被覆蓋后,調用子類方法時并不會自動調用父類方法
3.如果父類要禁止方法被子類覆蓋,可以使用final來聲明方法,這時如果子類仍要覆蓋父類方法,將會出錯
class MyClass { private $name = ""; public $num = 0; public $str = ""; public function __construct($name) { $this->name = $name; $this->num = 100; $this->str = "none"; } public function getName() { return $this->name; } } class MySubClass extends MyClass { public function __construct($name, $str) { parent::__construct($name); // 調用父類方法 $this->num = "0"; $this->str = $str; echo parent::getName()."\n"; // 調用父類方法 } public function getName() { return parent::getName()."$this->str\n"; // 調用父類方法 } } $b = new MySubClass("myName", true); // myName echo $b->getName(); // myName1 class MyClass { final public function getName() { } }
屬性重定義
在子類中,可以訪問父類中的public和protected屬性成員,除非重定義了同名的自有屬性,這時,父類中的屬性將無法訪問。
方法則不同,子類對方法進行覆蓋后,仍然可以訪問到父類方法。
class MyClass { public $a = 1; protected $b = 2; private $c = 3; public function f1() { echo "MyClass f1\n"; echo "\$a:$this->a; \$b:$this->b; \$c:$this->c;\n"; } protected function f2() { echo "MyClass f2\n"; echo "\$a:$this->a; \$b:$this->b; \$c:$this->c;\n"; } private function f3() { echo "MyClass f3\n"; } } class MySubClass extends MyClass { public $b = 22; public $c = 33; public function f1() { echo "MySubClass f1\n"; // 繼承到父類中的$a屬性,直接使用 echo "\$a:$this->a; \$b:$this->b; \$c:$this->c;\n"; // 調用父類中的同名方法 parent::f1(); // 繼承到父類中的f2()方法,直接使用 $this->f2(); } // 父類的f3()是私有的,這里的定義與父類無關 public function f3() { echo "MySubClass f3\n"; } } $b = new MySubClass; $b->f1();echo "\n"; /* MySubClass f1 $a:1; $b:22; $c:33; MyClass f1 $a:1; $b:22; $c:3; MyClass f2 $a:1; $b:22; $c:3; */ $b->f3();echo "\n"; /* MySubClass f3 */
重定義父類(同名)屬性時,屬性的可訪問性可以變得更開放,但不能更嚴格,也就是說,父類中的public屬性,不能在子類中修改為private屬性。
如果通過子類對象調用父類方法,那么該父類方法在訪問屬性時,對于重定義了的同名屬性,public和protected的屬性將訪問到子類版本,private屬性將訪問到父類版本。也可以理解為,public和protected屬性可以被重定義(父類的版本被重定義,從而不存在了),而private并未被重定義(父類中的屬性仍然存在,通過父類方法進行訪問,與子類中是否有同名屬性毫不相干)。
class MyClass { public $a = 1; protected $b = 2; private $c = 3; public function f1() { echo "\$a:$this->a; \$b:$this->b; \$c:$this->c;\n"; } } class MySubClass extends MyClass { public $a = 11; // 必須為public protected $b = 22; // 必須為protected或public private $c = 33; public function f2() { echo "\$a:$this->a; \$b:$this->b; \$c:$this->c;\n"; } } $b = new MySubClass; $b->f1(); // $a:11; $b:22; $c:3; $b->f2(); // $a:11; $b:22; $c:33;
范圍解析操作符 ::
又冒號常用于訪問類常量、類靜態(tài)變量,也用于在方法覆蓋時調用父類版本。與其搭配的還包括parent、self、static等關鍵字。
class MyClass { const Name0 = "MyClass"; // 類常量 public static $id0 = 0; // 類變量 public function put() { // 將被子類覆蓋的方法 echo "MyClass put()\n"; } } class MySubClass extends MyClass { const Name1 = "MySubClass"; public static $id1 = 1; public function put() { parent::put(); // 調用父類版本的對象方法 echo parent::Name0 . "\n"; // 父類常量 echo parent::$id0 . "\n"; // 父類變量 echo self::Name1."\n"; // 子類常量 echo self::$id1 . "\n"; // 子類變量 echo static::Name1 . "\n"; // 子類常理 echo static::$id1 . "\n"; // 子類變量 } } $a = "MyClass"; $ca = new MyClass; $cb = new MySubClass; $cb->put(); echo MyClass::Name0 . "\n"; echo MyClass::$id0 . "\n"; echo $a::Name0 . "\n"; echo $a::$id0 . "\n"; echo $ca::Name0 . "\n"; echo $ca::$id0 . "\n";
在子類中訪問父類中的成員時,應避免直接使用父類類名,而應使用parent::,以免破壞父類的封裝性。
final
聲明為final的方法不能被子類覆蓋,如果類聲明為final,則此類不能被繼承。
// 聲明為final的類不能被繼承 final class MyClass { private $dat; public function __construct($dat) { $this->dat = $dat; } // final方法不能被覆蓋,不過此類已經(jīng)是final類,方法無必要在聲明為final了 final public function getDat() { return $this->dat; } }
總結
以上所述是小編給大家介紹的php中的類與對象(繼承),希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關文章
php強制文件下載而非在瀏覽器打開的自定義函數(shù)分享
這篇文章主要介紹了php強制文件下載而非在瀏覽器打開的自定義函數(shù)分享,需要的朋友可以參考下2014-05-05PHP 中 var_export、print_r、var_dump 調試中的區(qū)別
這篇文章主要介紹了PHP 中 var_export、print_r、var_dump 調試中的區(qū)別,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-06-06分享六個比較好用的php數(shù)組Array函數(shù)
這篇文章給大家分享六個比較好用的php數(shù)組Array函數(shù),非常不錯,具有一定的參考借鑒價值,需要的朋友參考下吧2018-07-07如何通過PHP安裝數(shù)據(jù)庫并使數(shù)據(jù)初始化
這篇文章主要介紹了如何通過PHP安裝數(shù)據(jù)庫并使數(shù)據(jù)初始化,其實原理就是通過構建原生SQL來創(chuàng)建并初始化數(shù)據(jù)庫,連接數(shù)據(jù)庫、創(chuàng)建數(shù)據(jù)庫、使用數(shù)據(jù)庫、創(chuàng)建數(shù)據(jù)表、新增數(shù)據(jù)、關閉連接,本文給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧2024-03-03Yii2實現(xiàn)中國省市區(qū)三級聯(lián)動實例
本篇文章主要介紹了Yii2實現(xiàn)中國省市區(qū)三級聯(lián)動實例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-02-02