亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

用子接口作為新參數覆蓋方法參數

用子接口作為新參數覆蓋方法參數

PHP
海綿寶寶撒 2019-11-04 13:59:20
我不知道為什么此代碼在PHP中不起作用?<?phpinterface Engine {    function run();}interface HydroEngine extends Engine {    function run();}interface Car {    function setEngine(Engine $engine);}interface WaterCar extends Car {    function setEngine(HydroEngine $engine);}?>看來它沒有違反任何OOP規則,但是為什么它給我一個錯誤?Fatal error: Declaration of WaterCar::setEngine() must be compatible with Car::setEngine(Engine $engine)
查看完整描述

3 回答

?
莫回無

TA貢獻1865條經驗 獲得超7個贊

它確實違反了SOLID規則。您聲明Car::setEngine接受一個類型的參數Engine,但子級WaterCar::setEngine接受一個類型的參數HydroEngine。即使HydroEngine是的子類型Engine,它仍然是不同的類型。


當上課的時候Foo implements WaterCar,上課也是正確的instanceof Car。但是Foo::setEngine接受一個HydroEngine,但是不接受一個Engine。因此,Foo::setEngine據推測implements Car,但不接受type參數Engine。這打破了Liskov替代原則。您不能在子接口,周期中更改參數的類型。


繼承的關鍵字是明確的extends。子類與父類完全相同,甚至可能更多。它不能做的比父項少。既然HydroEngine是一個專門亞型Engine,這將意味著一個WaterCar不小于比Car,因為它只接受的更窄的亞型Engine。例如:


function (Car $car) {

    $engine = new EngineImplementation;

    $car->setEngine($engine);

}

如果您傳入,則上面的代碼會崩潰WaterCar,因為它不接受Engine。


查看完整回答
反對 回復 2019-11-04
?
慕田峪9158850

TA貢獻1794條經驗 獲得超8個贊

我認為方法簽名仍然需要完全相同,因為在編譯時,如果HydroEngine是Engine,則無法解決。


interface WaterCar extends Car {

    function setEngine(Engine $engine);

}


查看完整回答
反對 回復 2019-11-04
?
萬千封印

TA貢獻1891條經驗 獲得超3個贊

考慮一個實例$wc,該實例實現WaterCar并傳遞給期望實現的函數/方法Engine。它通過測試對象instanceof(Engine),然后將a傳遞IonEngine給水車實例... boom。我知道埃菲爾是唯一允許協變重新定義的語言。

查看完整回答
反對 回復 2019-11-04
  • 3 回答
  • 0 關注
  • 368 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號