Bagaimana antara muka PHP sebenarnya mengubah tingkah laku kelas
P粉289775043
P粉289775043 2023-09-02 23:49:28
0
1
517

Menurut dokumentasi PHP,

Antara muka objek membolehkan anda mencipta kod yang menentukan kaedah yang mesti dilaksanakan oleh kelas tanpa menentukan cara kaedah tersebut dilaksanakan.

Oleh itu, antara muka adalah seperti kelas dengan kaedah pratakrif yang masih perlu diakses menggunakan ->

Walau bagaimanapun, antara muka ArrayAccess menyediakan akses kepada objek sebagai tatasusunan. Objek boleh diakses menggunakan $object->property dan $object["property"]

Saya tidak dapat memahami bagaimana ArrayAccess memungkinkan untuk menukar sintaks objek. Saya menulis sekeping kod untuk cuba meniru kesan kaedah ArrayAccesshanya satu, tetapi ia menimbulkan ralat

// Menggunakan Antara Muka PHP ArrayAccess ruang nama A { kelas myclass melaksanakan ArrayAccess { public function offsetExists($offset) { return true } fungsi awam offsetGet($offset) { // berubah tingkah laku kembalikan $this->{$offset} ?? } fungsi awam offsetSet($offset, $value) {} fungsi awam offsetUnset($offset) {} } $myclass = new myclass(); $myclass->access = 'Antaramuka'; echo $myclass['access']; // "Antaramuka" }; //Cuba untuk melaksanakan Antara Muka ArrayAccess saya sendiri ruang nama B { antara muka MyArrayAccess { fungsi awam offsetGet($offset); } kelas myclass melaksanakan MyArrayAccess { fungsi awam offsetGet($offset) { // ubah tingkah laku kembalikan $this->{$offset} ?? } } $myclass = new myclass(); $myclass->access = 'Antaramuka'; echo $myclass['access']; // Ralat maut: Ralat Tidak Ditangkap: Tidak boleh menggunakan objek jenis Bmyclass sebagai tatasusunan }  

Tolong bantu saya menerangkannya dengan betul. Terima kasih

P粉289775043
P粉289775043

membalas semua (1)
P粉702946921

Saya tidak mengatakan bahawa antara muka "mengubah tingkah laku kelas", saya mengatakan bahawa antara muka memudahkan untukmelanjutkankefungsian kelas.

Untuk memahami antara muka, sebagai konsep pengaturcaraan berorientasikan objek, kita harus terlebih dahulu memahami masalah yang ingin diselesaikan.

Apakah masalah yang ingin diselesaikan oleh "Antara Muka"?

Antara muka ialahkontrak. Begini cara untuk melaksanakanpenaipan itikdalam PHP. Anda perlu berfikir dari perspektif penulis perpustakaan yang ingin mendedahkan fungsi kepada orang lain. Contohnya,

class Greeter { public function greet($person) { echo "Hello, {$person->getName()}!\n"; } }

Untuk memastikan pengguna perpustakaan mengetahui kaedah$person需要有getName()方法,您可以创建一个类Person> 有一个getName(). Kemudian gunakantaip pengisytiharanuntuk mengesan kemungkinan ralat apabila kod diselesaikan.

class Greeter { public function greet(Person $person) { echo "Hello, {$person->getName()}!\n"; } } class Person { public string $name; public function getName(): string { return $this->name; } }

Andaikan ada perpustakaan lain yang menyuap sesuatu dengan makanan:

class Feeder { public function feed(Eater $eater, string $food) { $eater->eat($food); } } class Animal { private $stomach = []; public function eat(string $food) { $stomach = $food; } }

Pertimbangkan ini...

Sekarang, katakan pengguna ingin menulis fungsi yang boleh makan dan bertanya khabarPet类。用户不想仅仅为了PetTulis semula fungsi ini.

Bagaimana menulisPet以便同时使用GreeterFeederperpustakaan?

Mungkin ini kesnya?

class Pet extends Person, Animal { }

Malangnya, PHPtidak menyokong pelbagai warisan. Satu kelas hanya boleh mempunyai satu kelas. Kod di atas tidak sah. Jadi dalam keadaan semasa, pengguna hanya boleh menggunakan salah satu perpustakaan.扩展

Selain itu, "nama" boleh menjadi konsep yang sangat berbeza untuk perkara yang berbeza (mis. seseorang mungkin menggunakan kaedah

.getName() 返回$first_name$last_name代码>)。您的库类中可能没有合理的默认实现getName()

Jadi, sebagai penulis perpustakaan, anda mahu perpustakaannya sefleksibel mungkin untuk pengguna. apa yang kau boleh buat?

Bagaimana untuk menyelesaikan masalah ini menggunakan "antara muka" dalam PHP?

Antara muka ialah pengisytiharan tandatangan kaedah. Ini ialah cara cepat untuk mengisytiharkan keperluan perpustakaan tanpa keperluan kelas/warisan konkrit.

Menggunakan antara muka anda boleh menulis semula kedua-dua perpustakaan seperti ini:

perpustakaanGreeter
class Greeter { public function greet(Namer $namer) { echo "Hello, {$namer->getName()}!\n"; } } interface Namer { public function getName(): string; }

perpustakaanFeeder
class Feeder { public function feed(Eater $eater, string $food) { $eater->eat($food); } } interface Eater { public function eat(string $food); }

Tidak memerlukan kelas tertentu (atau warisan kelas induk), kelas boleh melaksanakan berbilang antara muka. Jadi kelas

berikut sah sepenuhnya dalam PHP:Pet

class Pet implements Namer, Eater { private array $stomach = []; private string $name = ''; public function __construct(string $name) { $this->name = $name; } /** * Implements Namer. */ public function getName(): string { return $this->name; } /** * Implements Eater. */ public function eat(string $food) { $this->stomach[] = $food; } } $greeter = new Greeter(); $feeder = new Feeder(); $pet = new Pet('Paul'); $greeter->greet($pet); $feeder->feed($pet, 'a biscuit');
Kini, objek kelas

ini boleh digunakan dengan perpustakaanPet类的对象可以与Greeter库和Feederdan perpustakaan

.

ArrayAccess

Bagaimana pula dengan antara muka?

Antara mukaArrayAccess

tidak diisytiharkan oleh penulis perpustakaan antara muka pihak ketiga, tetapi ditulis oleh penulis teras PHP. Penulis PHP teras menyediakan sokongan yang lebih mendalam untuk ini.

Agak seperti antara muka yang kami nyatakan sebelum ini, PHP menyediakan fungsi kepada kelas yang melaksanakannya. Tetapi bukannya menyediakanGreeterFeedercontoh di atas, teras PHP menyediakansintaktik gulauntuk kelas yang melaksanakan ArrayAccess. Ini bermakna anda boleh menggunakankod yang lebih ringkasapabila berurusan dengan kelas yang melaksanakan antara muka AccessAccess.

Dalam contoh rasmi,

container = array( "one" => 1, "two" => 2, "three" => 3, ); } public function offsetSet($offset, $value) { if (is_null($offset)) { $this->container[] = $value; } else { $this->container[$offset] = $value; } } public function offsetExists($offset) { return isset($this->container[$offset]); } public function offsetUnset($offset) { unset($this->container[$offset]); } public function offsetGet($offset) { return isset($this->container[$offset]) ? $this->container[$offset] : null; } }

Jika anda melaksanakannya, gantikan dengan:

$obj = new Obj; $obj->offsetSet(10, "hello"); $obj->offsetSet(11, "world"); if ($obj->offsetUnset(12)) { $obj->offsetUnset(12); } echo $obj->offsetGet(11);

Anda boleh menggunakan$objdengan sintaks seperti tatasusunan untuk menjadikan kod anda lebih pendek:

$obj = new Obj; $obj[10] = "hello"; $obj[11] = "world"; if (isset($obj[12])) { unset($obj[12]); } echo $obj[11];
    Muat turun terkini
    Lagi>
    kesan web
    Kod sumber laman web
    Bahan laman web
    Templat hujung hadapan
    Tentang kita Penafian Sitemap
    Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!