php中的類與對象繼承詳解

來源:互聯網
上載者:User
在php中,類型的繼承使用extends關鍵字,而且最多隻能繼承一個父類,php不支援多繼承。本文主要和大家分享的是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();  // 3echo $b->getDat();  // dat: 4

方法覆蓋

包括建構函式在內,子類可以重新定義同名的類方法以覆蓋父類方法。覆蓋時遵循以下規則:

1.除建構函式之外,其他函數在覆蓋時,函數的參數列表必須相同

2.包括建構函式在內,方法被覆蓋後,調用子類方法時並不會自動調用父類方法

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);  // myNameecho $b->getName();          // myName1class 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;

範圍解析操作符 ::

又冒號常用於訪問類常量、類靜態變數,也用於在方法覆蓋時調用父類版本。與其搭配的還包括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方法不能被覆蓋,不過此類已經是final類,方法無必要在聲明為final了  final public  function getDat() { return $this->dat; }}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.