Rumah > Soal Jawab > teks badan
P粉7029469212023-09-03 20:17:24
Saya tidak mengatakan bahawa antara muka "mengubah tingkah laku kelas", saya mengatakan bahawa antara muka memudahkan untuk melanjutkan kefungsian kelas.
Untuk memahami antara muka, sebagai konsep pengaturcaraan berorientasikan objek, kita harus terlebih dahulu memahami masalah yang ingin diselesaikan.
Antara muka ialah kontrak. Begini cara untuk melaksanakan penaipan itik dalam 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 gunakan taip pengisytiharan untuk 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; } }
Sekarang, katakan pengguna ingin menulis fungsi yang boleh makan dan bertanya khabar Pet
类。用户不想仅仅为了 Pet
Tulis semula fungsi ini.
Bagaimana menulis Pet
以便同时使用 Greeter
和 Feeder
perpustakaan?
Mungkin ini kesnya?
class Pet extends Person, Animal { }
Malangnya, PHP tidak 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. 扩展
. getName() 返回
$first_name
和 $last_name
代码>)。您的库类中可能没有合理的默认实现 getName()
Bagaimana untuk menyelesaikan masalah ini menggunakan "antara muka" dalam PHP?
Menggunakan antara muka anda boleh menulis semula kedua-dua perpustakaan seperti ini:
Greeter
class Greeter { public function greet(Namer $namer) { echo "Hello, {$namer->getName()}!\n"; } } interface Namer { public function getName(): string; }
Feeder
class Feeder { public function feed(Eater $eater, string $food) { $eater->eat($food); } } interface Eater { public function eat(string $food); }
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 perpustakaan Pet
类的对象可以与 Greeter
库和 Feeder
dan perpustakaan
ArrayAccess
Agak seperti antara muka yang kami nyatakan sebelum ini, PHP menyediakan fungsi kepada kelas yang melaksanakannya. Tetapi bukannya menyediakan Greeter
或 Feeder
contoh di atas, teras PHP menyediakan sintaktik gula untuk kelas yang melaksanakan ArrayAccess. Ini bermakna anda boleh menggunakan kod yang lebih ringkas apabila berurusan dengan kelas yang melaksanakan antara muka AccessAccess.
Dalam contoh rasmi,
<?php class Obj implements ArrayAccess { private $container = array(); public function __construct() { $this->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 $obj
dengan 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];