本文實(shí)例講述了PHP 使用 Trait 解決 PHP 單繼承問題。分享給大家供大家參考,具體如下:
什么是繼承?
繼承實(shí)際上是存在于面向?qū)ο蟪绦蛟O(shè)計(jì)中的兩個(gè)類之間的一種關(guān)系,是面向?qū)ο蟪绦蛟O(shè)計(jì)方法的一個(gè)重要手段,通過繼承可以更有效地組織程序結(jié)構(gòu),明確類間的關(guān)系,充分利用已有的類來完成更復(fù)雜、更深入的開發(fā)。
當(dāng)一個(gè)類擁有另一個(gè)類的所有數(shù)據(jù)和操作時(shí),就稱這兩個(gè)類之間具有繼承關(guān)系。
被繼承的類稱為父類,繼承了父類的所有數(shù)據(jù)和操作的類稱為子類。
在 PHP 中用 extends 表明子類與父類的繼承關(guān)系。
在面向?qū)ο蟮某绦蛟O(shè)計(jì)中,采用繼承的方式來組織設(shè)計(jì)系統(tǒng)中的類,可以提高程序的抽象程度,更接近人的思維方式,使程序結(jié)構(gòu)更清晰并降低編碼和維護(hù)的工作量。
- 單繼承是指任何一個(gè)類都只有一個(gè)單一的父類,其結(jié)構(gòu)可以用單純的樹狀結(jié)構(gòu)來表示;
- 多繼承是指一個(gè)類可以有一個(gè)以上的父類,它的靜態(tài)的數(shù)據(jù)屬性和操作從所有這些父類中繼承,其結(jié)構(gòu)應(yīng)以復(fù)雜的網(wǎng)狀結(jié)構(gòu)來表示。
PHP 僅支持單繼承,而多繼承是通過接口或者 Trait 來實(shí)現(xiàn)的。
PHP 的單繼承示例:
// 單繼承:一個(gè)子類只能有一個(gè)父類
class A{
function show() {
echo "A";
}
}
class B{
function show() {
echo "B";
}
}
class C extends A{
}
$c = new C;
$c->show();
使用 Trait 解決 PHP 的單繼承
自 PHP 5.4.0 起,PHP 實(shí)現(xiàn)了一種代碼復(fù)用的方法,稱為 trait。
- Trait 是為類似 PHP 的單繼承語言而準(zhǔn)備的一種代碼復(fù)用機(jī)制
- Trait 為了減少單繼承語言的限制,使開發(fā)人員能夠自由地在不同層次結(jié)構(gòu)內(nèi)獨(dú)立的類中復(fù)用 method
- Trait 和 Class 組合的語義定義了一種減少復(fù)雜性的方式,避免傳統(tǒng)多繼承和 Mixin 類相關(guān)典型問題
- 無法通過 trait 自身來實(shí)例化
示例:
?php
trait Reader{
public function add($var1,$var2){
return $var1+$var2;
}
}
trait writer {
public function multiplication($var1,$var2){
return $var1*$var2;
}
}
class File {
use Reader;
use writer;
public function calculate($var1,$var2){
echo "Ressult of addition:".$this->add($var1,$var2) ."\n";
echo "Ressult of multiplication:".$this->multiplication($var1,$var2);
}
}
$o = new File();
$o->calculate(5,3);
多個(gè) trait
通過逗號分隔,在 use 聲明列出多個(gè) trait,可以都插入到一個(gè)類中。
?php
trait Hello {
public function sayHello() {
echo 'Hello ';
}
}
trait World {
public function sayWorld() {
echo 'World';
}
}
class MyHelloWorld {
use Hello, World;
public function sayExclamationMark() {
echo '!';
}
}
$o = new MyHelloWorld();
$o->sayHello();
$o->sayWorld();
$o->sayExclamationMark();
沖突的解決
如果兩個(gè) trait 都插入了一個(gè)同名的方法,如果沒有明確解決沖突將會(huì)產(chǎn)生一個(gè)致命錯(cuò)誤。
為了解決多個(gè) trait 在同一個(gè)類中的命名沖突,需要使用 insteadof 操作符來明確指定使用沖突方法中的哪一個(gè)。
以上方式僅允許排除掉其它方法,as 操作符可以 為某個(gè)方法引入別名。 注意,as 操作符不會(huì)對方法進(jìn)行重命名,也不會(huì)影響其方法。
示例:
?php
trait A {
public function smallTalk() {
echo 'a';
}
public function bigTalk() {
echo 'A';
}
}
trait B {
public function smallTalk() {
echo 'b';
}
public function bigTalk() {
echo 'B';
}
}
class Talker {
use A, B {
B::smallTalk insteadof A;
A::bigTalk insteadof B;
}
}
class Aliased_Talker {
use A, B {
B::smallTalk insteadof A;
A::bigTalk insteadof B;
B::bigTalk as talk;
}
}
從 trait 來組成 trait
正如 class 能夠使用 trait 一樣,其它 trait 也能夠使用 trait。在 trait 定義時(shí)通過使用一個(gè)或多個(gè) trait,能夠組合其它 trait 中的部分或全部成員。
?php
trait Hello {
public function sayHello() {
echo 'Hello ';
}
}
trait World {
public function sayWorld() {
echo 'World!';
}
}
trait HelloWorld {
use Hello, World;
}
class MyHelloWorld {
use HelloWorld;
}
$o = new MyHelloWorld();
$o->sayHello();
$o->sayWorld();
Trait 的抽象成員
為了對使用的類施加強(qiáng)制要求,trait 支持抽象方法的使用。
?php
trait Hello {
public function sayHelloWorld() {
echo 'Hello'.$this->getWorld();
}
abstract public function getWorld();
}
class MyHelloWorld {
private $world;
use Hello;
public function getWorld() {
return $this->world;
}
public function setWorld($val) {
$this->world = $val;
}
}
Trait 的靜態(tài)成員
Traits 可以被靜態(tài)成員靜態(tài)方法定義。
?php
// 靜態(tài)成員
trait Counter {
public function inc() {
static $c = 0;
$c = $c + 1;
echo "$c\n";
}
}
class C1 {
use Counter;
}
class C2 {
use Counter;
}
$o = new C1(); $o->inc(); // echo 1
$p = new C2(); $p->inc(); // echo 1
?php
// 靜態(tài)方法
trait StaticExample {
public static function doSomething() {
return 'Doing something';
}
}
class Example {
use StaticExample;
}
Example::doSomething();
?php
// 定義屬性
trait PropertiesTrait {
public $x = 1;
}
class PropertiesExample {
use PropertiesTrait;
}
$example = new PropertiesExample;
$example->x;
參考:
https://www.php.net/manual/zh/language.oop5.traits.php
https://learnku.com/php/t/37694
https://www..com/what-is-traits-in-php
更多關(guān)于PHP相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《php面向?qū)ο蟪绦蛟O(shè)計(jì)入門教程》、《PHP數(shù)組(Array)操作技巧大全》、《PHP基本語法入門教程》、《PHP運(yùn)算與運(yùn)算符用法總結(jié)》、《php字符串(string)用法總結(jié)》、《php+mysql數(shù)據(jù)庫操作入門教程》及《php常見數(shù)據(jù)庫操作技巧匯總》
希望本文所述對大家PHP程序設(shè)計(jì)有所幫助。
您可能感興趣的文章:- PHP Trait代碼復(fù)用類與多繼承實(shí)現(xiàn)方法詳解
- PHP中的Trait 特性及作用
- PHP中trait使用方法詳細(xì)介紹
- PHP中Trait及其應(yīng)用詳解
- 淺談PHP中的Trait使用方法
- PHP中的traits簡單使用實(shí)例
- PHP中的traits實(shí)現(xiàn)代碼復(fù)用使用實(shí)例
- PHP的Trait機(jī)制原理與用法分析
- php 多繼承的幾種常見實(shí)現(xiàn)方法示例
- PHP接口多繼承及tarits實(shí)現(xiàn)多繼承效果的方法