一、概念
繼承是面向對象編程中一個非常重要的特性,在 PHP 的對象模型中,繼承關系可以用于擴展已有類的功能,從而減少代碼的重復和提高代碼的可維護性。子類可以通過 extends 關鍵字來繼承父類的屬性和方法,會自動繼承父類的 public 和 protected 屬性和方法,但不會繼承私有屬性和方法。如果子類需要訪問父類的私有屬性或方法,可以通過在父類中定義公有或受保護的方法來實現(xiàn)。
當子類繼承了父類的方法時,這些方法都會保留其原有的功能,除非子類覆蓋了這些方法。子類可以通過重載(即覆蓋)父類的方法來實現(xiàn)自己的功能,從而實現(xiàn)對父類的擴展和重用。同時,子類也可以通過調用 parent:: 方法名 來調用父類中被覆蓋的方法,從而實現(xiàn)對父類方法的擴展。
通過繼承,PHP 中的類與類、對象與對象之間形成了一種層次結構,從而實現(xiàn)了代碼的分層和組織。這種層次結構可以讓我們更好地管理和維護代碼,同時也提高了代碼的可重用性和可擴展性。另外,繼承有助于功能的設計和抽象,在實現(xiàn)類似的對象、增加新功能時,無須重復編寫這些公用的功能。
子類無法訪問父類的私有方法。 因此,子類無需考慮正常的繼承規(guī)則而重新實現(xiàn)私有方法。 然而,在 PHP 8.0.0 之前, 和 的限制會應用于 private 方法。 從 PHP 8.0.0 開始,僅 的構造器是唯一受限的 private 方法; 想要“禁用”構造器,我們通常用靜態(tài)工廠方法作為代替。 finalstaticprivate final
注意:
- 除非使用了自動加載,否則一個類必須在使用之前被定義。 如果一個類擴展了另一個,則父類必須在子類之前被聲明。 此規(guī)則適用于類繼承其它類與接口。
- 不允許用只讀屬性重寫讀寫屬性,反之亦然。
<?php class A { public int $prop; } class B extends A { // Illegal: read-write -> readonly public readonly int $prop; } ?>
二、繼承示例
<?php class Foo { public function printItem($string) { echo 'Foo: ' . $string . PHP_EOL; } public function printPHP() { echo 'PHP is great.' . PHP_EOL; } } class Bar extends Foo { public function printItem($string) { echo 'Bar: ' . $string . PHP_EOL; } } $foo = new Foo(); $bar = new Bar(); $foo->printItem('baz'); // 輸出: 'Foo: baz' $foo->printPHP(); // 輸出: 'PHP is great' $bar->printItem('baz'); // 輸出: 'Bar: baz' $bar->printPHP(); // 輸出: 'PHP is great' ?>
三、返回類型與內部類兼容性
在 PHP 8.1 之前,大多數(shù)內部類或方法都沒有聲明它們的返回類型, 并且在擴展時允許任何返回類型。從 PHP 8.1.0 開始,大多數(shù)內部方法開始“暫時”聲明它們的返回類型, 在這種情況下,方法的返回類型應與要擴展的父項兼容,否則將發(fā)出棄用通知。
如果因為 PHP 跨版本兼容性問題而無法為重寫方法聲明返回類型, 可以添加 ReturnTypeWillChange 屬性來使棄用通知靜音。
重寫方法不聲明任何返回類型示例:
<?php class MyDateTime extends DateTime { public function modify(string $modifier) { return false; } } // "Deprecated: Return type of MyDateTime::modify(string $modifier) should either be compatible with DateTime::modify(string $modifier): DateTime|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice" as of PHP 8.1.0 ?>
重寫方法聲明了錯誤的返回類型示例:
<?php class MyDateTime extends DateTime { public function modify(string $modifier): ?DateTime { return null; } } // "Deprecated: Return type of MyDateTime::modify(string $modifier): ?DateTime should either be compatible with DateTime::modify(string $modifier): DateTime|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice" as of PHP 8.1.0 ?>
重寫方法在沒有棄用通知的情況下聲明錯誤的返回類型示例:
<?php class MyDateTime extends DateTime { /** * @return DateTime|false */ #[\ReturnTypeWillChange] public function modify(string $modifier) { return false; } } // No notice is triggered ?>