Kovarians Parameter dalam Kaedah Mengatasi
Dalam pengaturcaraan berorientasikan objek, kaedah mengatasi membenarkan subkelas untuk melaksanakan versi kaedah mereka sendiri yang ditakrifkan dalam superclass . Apabila mengatasi kaedah, walau bagaimanapun, parameter dan jenis pulangan mestilah serasi dengan pengisytiharan kaedah superclass.
Dalam kod yang diberikan, kami mempunyai senario dengan antara muka berikut:
<code class="php">interface Engine { function run(); } interface HydroEngine extends Engine { function run(); }</code>
Dan struktur serupa untuk kelas:
<code class="php">interface Car { function setEngine(Engine $engine); } interface WaterCar extends Car { // This method is intended to override Car::setEngine() function setEngine(HydroEngine $engine); }</code>
Isu timbul apabila cuba mengatasi setEngine() dalam WaterCar:
<code class="php">Fatal error: Declaration of WaterCar::setEngine() must be compatible with Car::setEngine(Engine $engine)</code>
Ralat ini berlaku kerana jenis parameter setEngine() dalam WaterCar ialah HydroEngine, subjenis Enjin, manakala jenis parameter dalam Kereta superclass ialah Enjin.
The Prinsip Penggantian Liskov (LSP) mengawal senario sedemikian. LSP menyatakan bahawa subjenis (cth., HydroEngine) mesti boleh digantikan untuk supertypenya (cth., Enjin) tanpa melanggar kefungsian program. Walau bagaimanapun, prinsip ini tidak terpakai pada jenis parameter dalam kaedah yang diganti.
Dalam kes ini, WaterCar tidak melaksanakan Car sepenuhnya kerana ia menerima jenis parameter yang lebih sempit dalam setEngine(). Ini kerana WaterCar hanya boleh menerima HydroEngines, manakala Kereta boleh menerima sebarang Enjin. Ini melanggar LSP dan melanggar kontrak yang ditetapkan oleh Kereta kelas super.
Untuk menyelesaikan isu ini, pastikan jenis parameter dalam kaedah ganti serasi dengan pengisytiharan kelas super. Dalam contoh ini, WaterCar::setEngine() boleh diubah suai seperti berikut:
<code class="php">function setEngine(Engine $engine): void;</code>
Pengubahsuaian ini mengekalkan keserasian dengan Car::setEngine() sambil membenarkan WaterCar mengkhusus dalam menerima HydroEngines.
Atas ialah kandungan terperinci Mengapa Saya Tidak Boleh Menggunakan Subjenis dalam Parameter Kaedah Ditindih?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!