PHP中的「過載」是個啥?

2022-06-05 06:48:10 字數 1781 閱讀 5441

很多面試官在面試的時候都會問一些物件導向的問題,物件導向的三大特性中,多型最主要的實現方式就是方法的過載和重寫。但是在php中,只有重寫,並沒有完全的過載能力的實現。

重寫,子類重寫父類方法。

// 重寫

class a

}class childa extends a

}$ca = new childa();

$ca->test(1);

這個在php中是沒有任何問題的,子類可以重寫父類的方法。當例項化子類的時候,呼叫的就是子類實現的重寫的方法。

過載,相同方法名但引數數量或者型別不同。

class a

// fatal error: cannot redeclare a::foo()

function foo($a, $b)

}

抱歉,這樣寫的結果將會是直接的報錯。php並不支援這樣的過載能力。而在php的官方手冊上,過載的定義是使用__set()、__get()、__call()、__callstatic()等魔術方法來對無法訪問的變數或方法進行過載。這與我們所學習的物件導向中的過載完全不同,在手冊中的note裡也有很多人對此提出了疑問。當然,我們今天並不會再去講這些魔術方法的使用。關於它們的使用可以參考我們之前寫過的文章:php中的那些魔術方法(一)、php的那些魔術方法(二)

那麼,在php中可以實現過載嗎?當然可以,只不過會麻煩一些:

// 過載

class b

else if (count($args) == 1) else

}private function fooadd($a, $b)

}$b = new b();

$b->foo(1);

$b->foo(1, 2);

使用乙個方法來呼叫其他方法,根據引數數量來進行判斷,就可以實現引數數量不同的方法過載。

// 使用__call()進行過載

class c

(...$args);}}

}private function foo1($a)

private function foo2($a, $b)

private function foo3($a, $b, $c)

}$c = new c();

$c->foo(1);

$c->foo(1, 2);

$c->foo(1, 2, 3);

使用__call()魔術方法或許會更簡單,但也會讓一些新手在接手專案的時候矇圈。畢竟魔術方法對ide是不友好的,這樣的開發讓__call()成為了乙個模板方法,由它來定義操作的演算法骨架。我們也可以根據引數型別來模擬過載能力。

// 引數型別不同的過載

class d else }}

private function fooint(int $a)

private function foostring(string $a)

}$d = new d();

$d->foo(1);

$d->foo('1');

不管怎麼說,用上述方法實現的方法過載都非常麻煩,因為會讓某乙個方法或者魔術方法非常重,它需要成為乙個控制器來根據引數對內部的方法進行排程。更多的情況下,我們應該還是使用不同的方法名然後抽象公共的部分提取成獨立的私有內部方法來實現不同方法名的「過載」。畢竟不同的語言還是要掌握它們不同的個性,並且根據這些個性靈活地運用在我們的專案中。

測試**:

參考文件:

b站id:482780532

PHP中的「過載」是個啥?

很多面試官在面試的時候都會問一些物件導向的問題,物件導向的三大特性中,多型最主要的實現方式就是方法的過載和重寫。但是在php中,只有重寫,並沒有完全的過載能力的實現。重寫,子類重寫父類方法。重寫 class a class childa extends a ca new childa ca test...

啥 啥 啥,服務治理是個啥

首先,先說下服務治理的邊界,本質上任何能提公升服務可用性,效能,讓服務更穩定等等,只要是能讓服務執行的更好,都屬於服務治理的範疇。服務治理比較常見的話題 服務發現,服務變更管理,服務監控,服務擴容縮容,服務自我保護,服務降級,服務授權防攻擊,服務上線驗證和灰度發布,服務問題定位和跟蹤,服務負載,服務...

vue中v model是個啥?

v model實際上只是一種語法糖,有時需要我們自定義去雙向繫結資料,這時候就需要對v model的實質有一定的了解了 當我們這樣寫時 something 複製 其實寫的是這樣乙個內容 something input something arguments 0 複製 所以當你想對乙個子元件的內容和父...