PHP berorientasikan objek
Apakah PHP berorientasikan objek?
Dalam pengaturcaraan berorientasikan objek (Bahasa Inggeris: Object-oriented programming, singkatan: OOP), An objek adalah keseluruhan yang terdiri daripada maklumat dan penerangan tentang cara memproses maklumat Ia adalah abstraksi dunia sebenar.
Di dunia nyata, perkara yang kita hadapi adalah objek, seperti komputer, televisyen, basikal, dll.
Cadangan pembelajaran berkaitan: "Pengaturcaraan Berorientasikan Objek PHP (Edisi Sutra Jantung Gadis Jade)", "Permulaan Pantas Pengaturcaraan Berorientasikan Objek MySQL "
Tiga ciri utama objek:
Kelakuan objek: apakah operasi yang boleh digunakan pada objek, membelok lampu hidup dan mati adalah tingkah laku.
Bentuk objek: bagaimana objek bertindak balas apabila kaedah tersebut digunakan, warna, saiz, rupa.
Perwakilan objek: Perwakilan objek adalah bersamaan dengan kad ID, khususnya membezakan perbezaan dalam kelakuan dan status yang sama.
Sebagai contoh, Haiwan ialah kelas abstrak Kita boleh menentukan anjing dan biri-biri, dan anjing dan biri-biri adalah objek konkrit dan boleh ditulis dan keadaan tingkah laku yang lain.
Kandungan berorientasikan objek
Kelas − mentakrifkan ciri abstrak sesuatu perkara. Takrif kelas termasuk bentuk data dan operasi pada data.
Objek − ialah contoh kelas.
Pembolehubah ahli − pembolehubah yang ditakrifkan di dalam kelas. Nilai pembolehubah ini tidak dapat dilihat oleh dunia luar, tetapi boleh diakses melalui fungsi ahli Selepas kelas dijadikan sebagai objek, pembolehubah boleh dipanggil atribut objek.
Fungsi ahli − ditakrifkan di dalam kelas dan boleh digunakan untuk mengakses data objek.
Warisan − Warisan ialah mekanisme untuk subkelas berkongsi struktur dan kaedah data kelas induk secara automatik. Ini adalah hubungan antara kelas. Apabila mentakrifkan dan melaksanakan kelas, anda boleh melakukannya berdasarkan kelas sedia ada, mengambil kandungan yang ditakrifkan oleh kelas sedia ada sebagai kandungan anda sendiri dan menambah beberapa kandungan baharu.
Kelas induk − Kelas diwarisi oleh kelas lain. Kelas ini boleh dipanggil kelas induk atau kelas asas atau kelas super.
Subkelas − Kelas yang mewarisi kelas lain dipanggil subkelas atau kelas terbitan.
Polymorphism − Polimorfisme bermaksud bahawa operasi atau fungsi atau proses yang sama boleh digunakan pada pelbagai jenis objek dan memperoleh hasil yang berbeza. Objek yang berbeza boleh menghasilkan hasil yang berbeza apabila menerima mesej yang sama Fenomena ini dipanggil polimorfisme.
Lebih muatan − Ringkasnya, ia adalah situasi di mana fungsi atau kaedah mempunyai nama yang sama tetapi senarai parameter yang berbeza dengan nama yang sama tetapi berbeza parameter Mereka memanggil satu sama lain fungsi atau kaedah terlebih beban.
Keabstrakan − Abstraksi merujuk kepada mengabstraksi objek dengan struktur data (atribut) dan gelagat (operasi) yang konsisten ke dalam kelas. Kelas ialah abstraksi yang mencerminkan sifat penting yang berkaitan dengan aplikasi sambil mengabaikan kandungan lain yang tidak berkaitan. Pembahagian mana-mana kelas adalah subjektif, tetapi mesti berkaitan dengan aplikasi tertentu.
Encapsulation − Enkapsulasi merujuk kepada mengikat sifat dan tingkah laku objek yang wujud dalam dunia nyata bersama-sama dan meletakkannya dalam unit logik.
Pembina − Digunakan terutamanya untuk memulakan objek semasa mencipta objek, iaitu, memberikan nilai awal kepada pembolehubah ahli objek dengan pengendali baharu untuk mencipta objek dalam pernyataan.
Pemusnah − Pemusnah (pemusnah) Bertentangan dengan pembina, apabila objek menamatkan kitaran hayatnya (contohnya, fungsi di mana objek terletak telah dipanggil ), sistem secara automatik melaksanakan pemusnah. Pemusnah selalunya digunakan untuk melakukan kerja "pembersihan" (contohnya, semasa mencipta objek, gunakan baharu untuk membuka ruang ingatan, yang harus dikeluarkan dengan pemadaman dalam pemusnah sebelum keluar).
Dalam gambar di bawah, kami telah mencipta tiga objek melalui kelas Kereta: Mercedes, Bmw dan Audi.
$mercedes = new Car (); $bmw = new Car (); $audi = new Car ();
Takrif kelas PHP
Kelas definisi PHP biasanya mempunyai format sintaks berikut:
<?php class phpClass { var $var1; var $var2 = "constant string"; function myfunc ($arg1, $arg2) { [..] } [..] } ?>dianalisis sebagai berikut:
kelas ditakrifkan menggunakan kata kunci kelas diikuti dengan nama kelas.
Pembolehubah dan kaedah boleh ditakrifkan dalam sepasang kurungan kerinting ({}) selepas nama kelas. Pembolehubah kelas
diisytiharkan menggunakan var dan pembolehubah juga boleh dimulakan dengan nilai.
Takrifan fungsi adalah serupa dengan takrifan fungsi PHP, tetapi fungsi hanya boleh diakses melalui kelas dan objek yang dibuatnya.
Instance
PHP_EOL ialah watak baris baharu.
Mencipta objek dalam PHP
Selepas kelas dibuat, kita boleh menggunakan operator baharu untuk membuat instantiate objek kelas ini:
<?php class Site { /* 成员变量 */ var $url; var $title; /* 成员函数 */ function setUrl($par){ $this->url = $par; } function getUrl(){ echo $this->url . PHP_EOL; } function setTitle($par){ $this->title = $par; } function getTitle(){ echo $this->title . PHP_EOL; } } ?>Dalam kod di atas, kami mencipta tiga objek Setiap satu daripada tiga objek adalah bebas Seterusnya, mari kita lihat cara mengakses kaedah ahli dan pembolehubah ahli.
Panggil kaedah ahli
Selepas membuat instantiat objek, kita boleh menggunakan objek untuk memanggil kaedah ahli Kaedah ahli objek hanya boleh mengendalikan pembolehubah ahli objek:
Panggil fungsi ahli, tetapkan tajuk dan URL
$php = new Site; $taobao = new Site; $google = new Site;panggil fungsi ahli, dapatkan tajuk dan URL
$php->setTitle( "php中文网" ); $taobao->setTitle( "淘宝" ); $google->setTitle( "Google 搜索" ); $php->setUrl( 'www.php.cn' ); $taobao->setUrl( 'www.taobao.com' ); $google->setUrl( 'www.google.com' );
Kod lengkap Seperti berikut:
Instance
$php->getTitle(); $taobao->getTitle(); $google->getTitle(); $php->getUrl(); $taobao->getUrl(); $google->getUrl();
Run Instance»
Klik "Run Instance" butang untuk melihat contoh dalam talian
Laksanakan kod di atas, hasil output ialah:
<?php class Site { /* 成员变量 */ var $url; var $title; /* 成员函数 */ function setUrl($par){ $this->url = $par; } function getUrl(){ echo $this->url . PHP_EOL; } function setTitle($par){ $this->title = $par; } function getTitle(){ echo $this->title . PHP_EOL; } } $php = new Site; $taobao = new Site; $google = new Site; // 调用成员函数,设置标题和URL $php->setTitle( "php中文网" ); $taobao->setTitle( "淘宝" ); $google->setTitle( "Google 搜索" ); $php->setUrl( 'www.php.cn' ); $taobao->setUrl( 'www.taobao.com' ); $google->setUrl( 'www.google.com' ); // 调用成员函数,获取标题和URL $php->getTitle(); $taobao->getTitle(); $google->getTitle(); $php->getUrl(); $taobao->getUrl(); $google->getUrl(); ?>
Pembina PHP
Pembina ialah kaedah khas. Ia digunakan terutamanya untuk memulakan objek apabila mencipta objek, iaitu, untuk menetapkan nilai awal kepada pembolehubah ahli objek Ia sentiasa digunakan bersama-sama dengan operator baru dalam pernyataan untuk mencipta objek.
PHP 5 membolehkan pembangun mentakrifkan kaedah sebagai pembina dalam kelas Format sintaks adalah seperti berikut:
php中文网 淘宝 Google 搜索 www.php.cn www.taobao.com www.google.comDalam contoh di atas, kita boleh memulakan melalui kaedah pembina. Pembolehubah $url dan $title:
void __construct ([ mixed $args [, $... ]] )Sekarang kita tidak perlu memanggil kaedah setTitle dan setUrl:
Instance
function __construct( $par1, $par2 ) { $this->url = $par1; $this->title = $par2; }
Jalankan contoh»
Klik butang "Jalankan contoh" untuk melihat contoh dalam talian
Pemusnah
Pemusnah (pemusnah) Bertentangan dengan pembina, apabila objek menamatkan kitaran hayatnya (contohnya, fungsi di mana objek terletak telah dipanggil), sistem secara automatik melaksanakan pemusnah.
PHP 5 memperkenalkan konsep pemusnah, yang serupa dengan bahasa berorientasikan objek lain Format sintaksnya adalah seperti berikut:
<?php class Site { /* 成员变量 */ var $url; var $title; function __construct( $par1, $par2 ) { $this->url = $par1; $this->title = $par2; } /* 成员函数 */ function setUrl($par){ $this->url = $par; } function getUrl(){ echo $this->url . PHP_EOL; } function setTitle($par){ $this->title = $par; } function getTitle(){ echo $this->title . PHP_EOL; } } $php = new Site('www.php.cn', 'php中文网'); $taobao = new Site('www.taobao.com', '淘宝'); $google = new Site('www.google.com', 'Google 搜索'); // 调用成员函数,获取标题和URL $php->getTitle(); $taobao->getTitle(); $google->getTitle(); $php->getUrl(); $taobao->getUrl(); $google->getUrl(); ?>Instance<🎜. >
void __destruct ( void )melaksanakan kod di atas, dan hasil output ialah:
<?php class MyDestructableClass { function __construct() { print "构造函数\n"; $this->name = "MyDestructableClass"; } function __destruct() { print "销毁 " . $this->name . "\n"; } } $obj = new MyDestructableClass(); ?>
Diwarisi PHP menggunakan kata kunci
lanjutkan untuk mewarisi kelas PHP tidak menyokong berbilang warisan Formatnya adalah seperti berikut:
构造函数 销毁 MyDestructableClass
class Child extends Parent { // 代码部分 }
Metode overridingJika kaedah yang diwarisi daripada kelas induk tidak dapat memenuhi keperluan subkelas, ia boleh ditulis semula Proses ini dipanggil method override, juga dikenali sebagai method rewriting. Kaedah getUrl dan getTitle ditindih dalam contoh:
<?php // 子类扩展站点类别 class Child_Site extends Site { var $category; function setCate($par){ $this->category = $par; } function getCate(){ echo $this->category . PHP_EOL; } }
Kawalan aksesPHP untuk atribut atau Kawalan capaian kaedah dicapai dengan menambahkan kata kunci awam, dilindungi atau peribadi di hadapan.
awam: Ahli kelas awam boleh diakses dari mana-mana sahaja.
dilindungi: Ahli kelas yang dilindungi boleh diakses dengan sendirinya dan subkelas dan kelas induknya.
peribadi (peribadi): Ahli kelas persendirian hanya boleh diakses oleh kelas di mana mereka ditakrifkan.
function getUrl() { echo $this->url . PHP_EOL; return $this->url; } function getTitle(){ echo $this->title . PHP_EOL; return $this->title; }
<?php /** * Define MyClass */ class MyClass { public $public = 'Public'; protected $protected = 'Protected'; private $private = 'Private'; function printHello() { echo $this->public; echo $this->protected; echo $this->private; } } $obj = new MyClass(); echo $obj->public; // 这行能被正常执行 echo $obj->protected; // 这行会产生一个致命错误 echo $obj->private; // 这行也会产生一个致命错误 $obj->printHello(); // 输出 Public、Protected 和 Private /** * Define MyClass2 */ class MyClass2 extends MyClass { // 可以对 public 和 protected 进行重定义,但 private 而不能 protected $protected = 'Protected2'; function printHello() { echo $this->public; echo $this->protected; echo $this->private; } } $obj2 = new MyClass2(); echo $obj2->public; // 这行能被正常执行 echo $obj2->private; // 未定义 private echo $obj2->protected; // 这行会产生一个致命错误 $obj2->printHello(); // 输出 Public、Protected2 和 Undefined ?>
Antaramuka Menggunakan antara muka, anda boleh menentukan kaedah yang mesti dilaksanakan oleh kelas, tetapi anda tidak perlu menentukan mereka Kandungan khusus kaedah. Antara muka ditakrifkan melalui kata kunci
antara muka, sama seperti mentakrifkan kelas standard, tetapi semua kaedah yang ditakrifkan di dalamnya adalah kosong.
Semua kaedah yang ditakrifkan dalam antara muka mestilah awam. Ini adalah ciri antara muka. Untuk melaksanakan antara muka, gunakan operatorimplements. Kelas mesti melaksanakan semua kaedah yang ditakrifkan dalam antara muka, jika tidak ralat maut akan dilaporkan. Kelas boleh melaksanakan berbilang antara muka Gunakan koma untuk memisahkan nama berbilang antara muka.
<?php /** * Define MyClass */ class MyClass { // 声明一个公有的构造函数 public function __construct() { } // 声明一个公有的方法 public function MyPublic() { } // 声明一个受保护的方法 protected function MyProtected() { } // 声明一个私有的方法 private function MyPrivate() { } // 此方法为公有 function Foo() { $this->MyPublic(); $this->MyProtected(); $this->MyPrivate(); } } $myclass = new MyClass; $myclass->MyPublic(); // 这行能被正常执行 $myclass->MyProtected(); // 这行会产生一个致命错误 $myclass->MyPrivate(); // 这行会产生一个致命错误 $myclass->Foo(); // 公有,受保护,私有都可以执行 /** * Define MyClass2 */ class MyClass2 extends MyClass { // 此方法为公有 function Foo2() { $this->MyPublic(); $this->MyProtected(); $this->MyPrivate(); // 这行会产生一个致命错误 } } $myclass2 = new MyClass2; $myclass2->MyPublic(); // 这行能被正常执行 $myclass2->Foo2(); // 公有的和受保护的都可执行,但私有的不行 class Bar { public function test() { $this->testPrivate(); $this->testPublic(); } public function testPublic() { echo "Bar::testPublic\n"; } private function testPrivate() { echo "Bar::testPrivate\n"; } } class Foo extends Bar { public function testPublic() { echo "Foo::testPublic\n"; } private function testPrivate() { echo "Foo::testPrivate\n"; } } $myFoo = new foo(); $myFoo->test(); // Bar::testPrivate // Foo::testPublic ?>
Malar
Anda boleh menentukan nilai yang sentiasa kekal tidak berubah dalam kelas sebagai pemalar. Tidak perlu menggunakan simbol $ apabila mentakrifkan dan menggunakan pemalar.
Nilai pemalar mestilah nilai tetap dan tidak boleh pembolehubah, atribut kelas, hasil operasi matematik atau panggilan fungsi.
Sejak PHP 5.3.0, anda boleh menggunakan pembolehubah untuk memanggil kelas secara dinamik. Tetapi nilai pembolehubah ini tidak boleh menjadi kata kunci (seperti diri, ibu bapa atau statik).
Instance
<?php // 声明一个'iTemplate'接口 interface iTemplate { public function setVariable($name, $var); public function getHtml($template); } // 实现接口 class Template implements iTemplate { private $vars = array(); public function setVariable($name, $var) { $this->vars[$name] = $var; } public function getHtml($template) { foreach($this->vars as $name => $value) { $template = str_replace('{' . $name . '}', $value, $template); } return $template; } }
Kelas abstrak
Mana-mana kelas, jika sekurang-kurangnya satu kaedah di dalamnya Diisytiharkan sebagai abstrak, maka kelas mesti diisytiharkan sebagai abstrak.
Kelas yang ditakrifkan sebagai abstrak tidak boleh dibuat seketika.
Kaedah yang ditakrifkan sebagai abstrak hanya mengisytiharkan kaedah panggilannya (parameter) dan tidak boleh menentukan pelaksanaan fungsi khususnya.
Apabila mewarisi kelas abstrak, subkelas mesti mentakrifkan semua kaedah abstrak dalam kelas induk selain itu, kawalan akses kaedah ini mestilah sama seperti dalam kelas induk (atau lebih santai). Sebagai contoh, jika kaedah abstrak diisytiharkan sebagai dilindungi, maka kaedah yang dilaksanakan dalam subkelas hendaklah diisytiharkan sebagai dilindungi atau awam, dan tidak boleh ditakrifkan sebagai peribadi. Di samping itu, kaedah panggilan kaedah mesti sepadan, iaitu jenis dan bilangan parameter yang diperlukan mestilah konsisten. Sebagai contoh, jika subkelas mentakrifkan parameter pilihan yang tidak disertakan dalam pengisytiharan kaedah abstrak kelas induk, tiada konflik antara kedua-dua pengisytiharan itu.
<?php class MyClass { const constant = '常量值'; function showConstant() { echo self::constant . PHP_EOL; } } echo MyClass::constant . PHP_EOL; $classname = "MyClass"; echo $classname::constant . PHP_EOL; // 自 5.3.0 起 $class = new MyClass(); $class->showConstant(); echo $class::constant . PHP_EOL; // 自 PHP 5.3.0 起 ?>melaksanakan kod di atas, dan hasil output ialah:
<?php abstract class AbstractClass { // 强制要求子类定义这些方法 abstract protected function getValue(); abstract protected function prefixValue($prefix); // 普通方法(非抽象方法) public function printOut() { print $this->getValue() . PHP_EOL; } } class ConcreteClass1 extends AbstractClass { protected function getValue() { return "ConcreteClass1"; } public function prefixValue($prefix) { return "{$prefix}ConcreteClass1"; } } class ConcreteClass2 extends AbstractClass { public function getValue() { return "ConcreteClass2"; } public function prefixValue($prefix) { return "{$prefix}ConcreteClass2"; } } $class1 = new ConcreteClass1; $class1->printOut(); echo $class1->prefixValue('FOO_') . PHP_EOL; $class2 = new ConcreteClass2; $class2->printOut(); echo $class2->prefixValue('FOO_') . PHP_EOL; ?>
Kata kunci statik
Mengisytiharkan atribut atau kaedah kelas sebagai statik membolehkan anda mengaksesnya secara langsung tanpa membuat seketika kelas.
Sifat statik tidak boleh diakses melalui objek kelas yang telah digunakan (tetapi kaedah statik boleh).
Memandangkan kaedah statik tidak memerlukan objek dipanggil, pembolehubah pseudo $ini tidak tersedia dalam kaedah statik.
Sifat statik tidak boleh diakses oleh objek melalui pengendali ->
Sejak PHP 5.3.0, anda boleh menggunakan pembolehubah untuk memanggil kelas secara dinamik. Tetapi nilai pembolehubah ini tidak boleh menjadi kata kunci sendiri, induk atau statik.
ConcreteClass1 FOO_ConcreteClass1 ConcreteClass2 FOO_ConcreteClass2melaksanakan program di atas, dan hasil output ialah:
<?php class Foo { public static $my_static = 'foo'; public function staticValue() { return self::$my_static; } } print Foo::$my_static . PHP_EOL; $foo = new Foo(); print $foo->staticValue() . PHP_EOL; ?>
Kata kunci akhir
PHP 5 menambah kata kunci akhir baharu. Jika kaedah dalam kelas induk diisytiharkan muktamad, kelas anak tidak boleh mengatasi kaedah tersebut. Jika kelas diisytiharkan muktamad, ia tidak boleh diwarisi.
Pelaksanaan kod berikut akan melaporkan ralat:
foo foo
Panggil pembina kelas induk
PHP akan bukan Pembina kelas secara automatik memanggil pembina kelas induk. Untuk melaksanakan pembina kelas induk, anda perlu memanggil parent::__construct() dalam pembina kelas anak.
<?php class BaseClass { public function test() { echo "BaseClass::test() called" . PHP_EOL; } final public function moreTesting() { echo "BaseClass::moreTesting() called" . PHP_EOL; } } class ChildClass extends BaseClass { public function moreTesting() { echo "ChildClass::moreTesting() called" . PHP_EOL; } } // 报错信息 Fatal error: Cannot override final method BaseClass::moreTesting() ?>melaksanakan program di atas, dan hasil output ialah:
<?php class BaseClass { function __construct() { print "BaseClass 类中构造方法" . PHP_EOL; } } class SubClass extends BaseClass { function __construct() { parent::__construct(); // 子类构造方法不能自动调用父类的构造方法 print "SubClass 类中构造方法" . PHP_EOL; } } class OtherSubClass extends BaseClass { // 继承 BaseClass 的构造方法 } // 调用 BaseClass 构造方法 $obj = new BaseClass(); // 调用 BaseClass、SubClass 构造方法 $obj = new SubClass(); // 调用 BaseClass 构造方法 $obj = new OtherSubClass(); ?>