English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Nel design orientato agli oggetti (OOP in inglese, abbreviato in OOP), un oggetto è un'entità composta da informazioni e descrizioni del trattamento delle informazioni, è un'astrazione del mondo reale.
Nel mondo reale, tutte le cose che affrontiamo sono oggetti, come computer, televisioni, biciclette, ecc.
Le tre principali caratteristiche degli oggetti:
Comportamento degli oggetti: le operazioni che possiamo applicare agli oggetti, accendere e spegnere la luce sono comportamenti.
Forma degli oggetti: quando si applicano metodi, come rispondono gli oggetti, colore, dimensione, forma.
Rappresentazione degli oggetti: la rappresentazione degli oggetti è simile a un documento d'identità, la differenza specifica risiede nei comportamenti e nelle condizioni identici.
Ad esempio, Animal(animale) è una classe astratta, possiamo specificare un cane e una pecora, e cane e pecora sono oggetti concreti, che hanno attributi come il colore e comportamenti come camminare e correre.
Classe − Definisce le caratteristiche astratte di una cosa. La definizione della classe include la forma dei dati e le operazioni sui dati.
Oggetto − È un esempio della classe.
Variabile membro − Definito all'interno della classe, le variabili di questo tipo sono invisibili all'esterno, ma possono essere accedute tramite funzioni membro. Dopo che la classe è esemplificata come oggetto, questa variabile può essere chiamata attributo dell'oggetto.
Funzione membro − Definito all'interno della classe, può essere utilizzato per accedere ai dati dell'oggetto.
继承 − L'ereditarietà è il meccanismo per cui la sottoclasse condivide automaticamente i dati e i metodi della classe padre, che è un tipo di relazione tra classi. Quando si definisce ed implementa una classe, è possibile farlo sulla base di una classe esistente, utilizzando il contenuto definito dalla classe esistente come proprio contenuto e aggiungendo nuovi contenuti.
Classe padre − Una classe che viene ereditata da un'altra classe può essere chiamata classe padre, classe base o classe superiore.
Sottoclasse − Un classe che eredita da un'altra classe viene chiamata sottoclasse, anche chiamata classe derivata.
Polimorfismo − Polimorfismo significa che le stesse funzioni o metodi possono agire su diversi tipi di oggetti e ottenere risultati diversi. Diversi oggetti possono produrre risultati diversi ricevendo lo stesso messaggio, questo fenomeno si chiama polimorfismo.
Sovraccarico − In sintesi, è la situazione in cui le funzioni o i metodi hanno lo stesso nome ma una lista di parametri diversa. Tali funzioni o metodi con lo stesso nome e parametri diversi si chiamano funzioni o metodi sovraccaricati.
Astrazione − L'astrazione significa astrare gli oggetti che hanno una struttura dati (proprietà) e comportamenti (operazioni) consistenti in una classe. Una classe è una tale astrazione che riflette le proprietà importanti relative all'applicazione, ignorando altri contenuti non rilevanti. La classificazione di qualsiasi classe è soggettiva, ma deve essere relativa all'applicazione specifica.
Encapsulation − Encapsulation significa associare le proprietà e i comportamenti di un oggetto esistente nel mondo reale in un'unità logica.
构造函数 − Principalmente utilizzato per inizializzare l'oggetto durante la creazione, ovvero assegnare valori iniziali alle variabili membro dell'oggetto, e viene sempre utilizzato insieme all'operatore new nelle istruzioni di creazione dell'oggetto.
funzione distruttiva − Il costruttore (constructor) è il contrario dell'distruttore, viene eseguito automaticamente dal sistema quando l'oggetto termina la sua vita (ad esempio quando la funzione in cui l'oggetto si trova è stata chiamata). L'distruttore viene spesso utilizzato per fare "pulizia e riordinamento" (ad esempio, quando si utilizza new per allocare un'area di memoria, dovrebbe essere liberata con delete prima di uscire).
Nella figura sottostante abbiamo creato tre oggetti attraverso la classe Car: Mercedes, Bmw e Audi.
$mercedes = new Car(); $bmw = new Car(); $audi = new Car();
La sintassi di definizione della classe PHP di solito è la seguente:
<?php class phpClass { var $var1; var $var2 = 'stringa costante'; function myfunc ($arg1, $arg2) { [..] } [..] } ?>
L'analisi è il seguente:
La classe utilizza class La parola chiave class followed by the class name defines.
Dopo la parola chiave della classe, possiamo definire variabili e metodi all'interno di un paio di parentesi graffe ({}).
Le variabili della classe utilizzano var per dichiarare, le variabili possono anche essere inizializzate con valori.
La definizione della funzione è simile alla definizione delle funzioni PHP, ma le funzioni possono essere accedute solo attraverso la classe e gli oggetti istanziati della classe.
<?php class Site { /* Variabile membro */ var $url; var $title; /* Funzione membro */ 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; } } ?>
variabile $this rappresenta l'oggetto stesso.
PHP_EOL per il carattere di newline.
Dopo aver creato la classe, possiamo utilizzare new Operatore per istanziare l'oggetto della classe:
$w3codebox = new Site; $taobao = new Site; $google = new Site;
Nel codice sopra abbiamo creato tre oggetti, tre oggetti sono indipendenti l'uno dall'altro, ora vediamo come accedere ai metodi membri e alle variabili membri.
Dopo aver istanziato l'oggetto, possiamo utilizzare l'oggetto per chiamare i metodi membri, i metodi membri possono solo operare sulle variabili membri dell'oggetto:
// Chiamata della funzione membro, impostazione del titolo e dell'URL $w3codebox->setTitle('基础教程网'); $taobao->setTitle('淘宝'); $google->setTitle('Google 搜索'); $w3codebox->setUrl('it.oldtoolbag.com'); $taobao->setUrl('www.taobao.com'); $google->setUrl('www.google.com'); // chiamata a funzione membro, ottenere titolo e URL $w3codebox->getTitle(); $taobao->getTitle(); $google->getTitle(); $w3codebox->getUrl(); $taobao->getUrl(); $google->getUrl();
Il codice completo è il seguente:
<?php class Site { /* Variabile membro */ var $url; var $title; /* Funzione membro */ 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; } } $w3codebox = new Site; $taobao = new Site; $google = new Site; // Chiamata della funzione membro, impostazione del titolo e dell'URL $w3codebox->setTitle('基础教程网'); $taobao->setTitle('天猫商城'); $google->setTitle('Google 搜索'); $w3codebox->setUrl('it.oldtoolbag.com'); $taobao->setUrl('www.tmall.com'); $google->setUrl('www.google.com'); // chiamata a funzione membro, ottenere titolo e URL $w3codebox->getTitle(); $taobao->getTitle(); $google->getTitle(); $w3codebox->getUrl(); $taobao->getUrl(); $google->getUrl(); ?>
Eseguendo il codice sopra, il risultato di output è:
Sito di base delle istruzioni Cassa del Tmall Google Ricerca it.oldtoolbag.com www.tmall.com www.google.com
Il costruttore è un metodo speciale. Serve principalmente per inizializzare l'oggetto durante la creazione dell'oggetto, ovvero assegnare valori iniziali ai variabili membro dell'oggetto, utilizzato insieme all'operatore new nella dichiarazione dell'oggetto.
PHP 5 permette agli sviluppatori di definire un metodo come costruttore all'interno di una classe, con la seguente sintassi:
void __construct ([ mixed $args[, $... ]]]
Nell'esempio sopra possiamo inizializzare le variabili $url e $title tramite il metodo costruttore:
function __construct( $par1, $par2 ) { $this->url = $par1; $this->title = $par2; }
Ora non dobbiamo chiamare più i metodi setTitle e setUrl:
$w3codebox = new Site('it.oldtoolbag.com', 'Sito di base delle istruzioni'); $tmall = new Site('www.tmall.com', 'Cassa del Tmall'); $google = new Site('www.google.com', 'Google Ricerca'); // chiamata a funzione membro, ottenere titolo e URL $w3codebox->getTitle(); $tmall->getTitle(); $google->getTitle(); $w3codebox->getUrl(); $tmall->getUrl(); $google->getUrl();
La funzione distruttiva (distruttore) è l'opposto del costruttore, viene eseguita automaticamente dal sistema quando l'oggetto termina la sua vita (ad esempio quando la funzione in cui l'oggetto si trova è stata chiamata)
PHP 5 ha introdotto il concetto di funzione distruttiva, simile ad altri linguaggi orientati agli oggetti, con la seguente sintassi:
void __destruct ( void )
<?php class MyDestructableClass { function __construct() { print "costruttore\n"; $this->name = "MyDestructableClass"; } function __destruct() { print "销毁 " . $this->name . "\n"; } } $obj = new MyDestructableClass(); ?>
Eseguendo il codice sopra, il risultato di output è:
构造函数 销毁 MyDestructableClass
PHP 使用关键字 extends 要继承一个类,PHP 不支持多继承,格式如下:
class Child extends Parent { // 代码部分 }
示例中 Child_Site 类继承了 Site 类,并扩展了功能:
<?php // 子类扩展站点类别 class Child_Site extends Site { var $category; function setCate($par){ $this->category = $par; } function getCate(){ echo $this->category . PHP_EOL; } }
如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫做方法的覆盖(override),也称为方法的重写。
示例中重写了 getUrl 与 getTitle 方法:
function getUrl() { echo $this->url . PHP_EOL; return $this->url; } function getTitle(){ echo $this->title . PHP_EOL; return $this->title; }
PHP 对属性或方法的访问控制是通过在前面添加关键字 public(公有)、protected(受保护)或 private(私有)来实现的。
public(公有):公有的类成员可以在任何地方被访问。
protected(受保护):受保护的类成员可以被其自身以及其子类和父类访问。
private(私有):私有的类成员只能被其定义所在的类访问。
类的属性必须定义为公有、受保护或私有之一。如果使用 var 定义,则被视为公有。
<?php /** * Definire 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; // Questo riga può essere eseguito normalmente echo $obj->protected; // Questo riga produrrà un errore fatale echo $obj->private; // Questo riga produrrà un errore fatale $obj->printHello(); // Output Public, Protected e Private /** * Definire MyClass2 */ class MyClass2 extends MyClass { // È possibile ridefinire public e protected, ma non private protected $protected = 'Protected2'; function printHello() { echo $this->public; echo $this->protected; echo $this->private; } } $obj2 = new MyClass2(); echo $obj2->public; // Questo riga può essere eseguito normalmente echo $obj2->private; // Non definito private echo $obj2->protected; // Questo riga produrrà un errore fatale $obj2->printHello(); // Output Public, Protected2 e Undefined ?>
I metodi della classe possono essere definiti come pubblici, privati o protetti. Se non vengono impostati questi keyword, il metodo diventa pubblico per default.
<?php /** * Definire MyClass */ class MyClass { // Dichiarare un costruttore pubblico public function __construct() { } // Dichiarare un metodo pubblico public function MyPublic() { } // Dichiarare un metodo protetto protected function MyProtected() { } // Dichiarare un metodo privato private function MyPrivate() { } // Questo metodo è pubblico function Foo() { $this->MyPublic(); $this->MyProtected(); $this->MyPrivate(); } } $myclass = new MyClass; $myclass->MyPublic(); // Questo riga può essere eseguito normalmente $myclass->MyProtected(); // Questo riga produrrà un errore fatale $myclass->MyPrivate(); // Questo riga produrrà un errore fatale $myclass->Foo(); // Pubblico, protetto e privato possono essere eseguiti /** /* Definizione di MyClass2 */ class MyClass2 extends MyClass { // Questo metodo è pubblico function Foo2() { $this->MyPublic(); $this->MyProtected(); $this->MyPrivate(); // Questa riga genererà un errore fatale } } $myclass2 = new MyClass2; $myclass2->MyPublic(); // Questa riga può essere eseguita normalmente $myclass2->Foo2(); // Gli pubblici e i protetti possono essere eseguiti, ma non i privati 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 ?>
Utilizzando l'interfaccia (interface), è possibile specificare quali metodi una classe deve implementare, senza definire il contenuto specifico di questi metodi.
Un'interfaccia è definita da interface La parola chiave per definire, come definire una classe standard, ma tutti i metodi definiti sono vuoti.
Tutti i metodi definiti nell'interfaccia devono essere pubblici, questa è una caratteristica dell'interfaccia.
Per implementare un'interfaccia, utilizzare implements L'operatore. La classe deve implementare tutti i metodi definiti nell'interfaccia, altrimenti viene generato un errore fatale. Una classe può implementare più interfacce, separando i nomi delle interfacce con la virgola.
<?php // Dichiarazione di un'interfaccia 'iTemplate' interface iTemplate { public function setVariable($name, $var); public function getHtml($template); } // Implementa l'interfaccia 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; } }
Puoi definire come costante un valore che rimane invariato nel contesto della classe. Non è necessario utilizzare il simbolo $ quando si definisce e si utilizza una costante.
Il valore della costante deve essere un valore costante, non può essere una variabile, una proprietà di classe, il risultato di un'operazione matematica o una chiamata di funzione.
Da PHP 5.3.0, è possibile chiamare dinamicamente una classe utilizzando una variabile. Tuttavia, il valore della variabile non può essere un nome riservato (come self, parent o static).
<?php class MyClass { const constant = 'Valore costante'; function showConstant() { echo self::constant . PHP_EOL; } } echo MyClass::constant . PHP_EOL; $classname = "MyClass"; echo $classname::constant . PHP_EOL; // Da 5.3.0 $class = new MyClass(); $class->showConstant(); echo $class::constant . PHP_EOL; // Da PHP 5.3.0 ?>
Qualsiasi classe che abbia almeno un metodo dichiarato come astratto deve essere dichiarata come astratta.
Le classi definite come astratte non possono essere istanziate.
I metodi dichiarati come astratti dichiarano solo il modo di chiamata (parametri), ma non possono definire l'esatta implementazione della funzione.
Quando si herda da una classe astratta, il sottoclasse deve definire tutti i metodi astratti della classe padre; inoltre, il controllo di accesso di questi metodi deve essere lo stesso (o più permissivo) di quello della classe padre. Ad esempio, se un metodo astratto è dichiarato come protetto, allora il metodo implementato nel sottoclasse dovrebbe essere dichiarato come protetto o pubblico, non come privato.
<?php abstract class AbstractClass { // si richiede che le sottoclassi definiscano questi metodi abstract protected function getValue(); abstract protected function prefixValue($prefix); // metodo normale (non astratto) 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; ?>
Eseguendo il codice sopra, il risultato di output è:
ConcreteClass1 FOO_ConcreteClass1 ConcreteClass2 FOO_ConcreteClass2
Inoltre, il metodo della sottoclasse può includere parametri opzionali che non esistono nel metodo astratto della classe padre.
Ad esempio, se la sottoclasse definisce un parametro opzionale mentre la dichiarazione del metodo astratto della classe padre non lo contiene, può funzionare normalmente.
<?php abstract class AbstractClass { // La nostra metodo astratto richiede solo definire i parametri necessari abstract protected function prefixName($name); } class ConcreteClass extends AbstractClass { // Le nostre sottoclassi possono definire parametri opzionali che non esistono nella firma del padre public function prefixName($name, $separator = ".") { if ($name == "Pacman") { $prefix = "Mr"; } elseif ($name == "Pacwoman") { $prefix = "Mrs"; } else { $prefix = ""; } return "{$prefix}{$separator} {$name}"; } } $class = new ConcreteClass; echo $class->prefixName("Pacman"), "\n"; echo $class->prefixName("Pacwoman"), "\n"; ?>
Il risultato dell'output è:
Mr. Pacman Mrs. Pacwoman
Dichiarando le proprietà o i metodi della classe come static (statici), è possibile accedervi direttamente senza istanziare la classe.
Le proprietà statiche non possono essere accedute tramite un oggetto già istanziato della classe (ma i metodi statici possono essere chiamati).
Poiché i metodi statici possono essere chiamati senza un oggetto, il segnaposto $this non è disponibile nei metodi statici.
Le proprietà statiche non possono essere accedute tramite l'operatore -> da parte di un oggetto.
Da PHP 5.3.0 in poi, è possibile chiamare dinamicamente una classe utilizzando una variabile. Tuttavia, il valore di tale variabile non può essere i termini chiave self, parent o static.
<?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; ?>
Eseguendo il programma sopra, il risultato di output sarà:
foo foo
PHP 5 ha introdotto una parola chiave final. Se un metodo della classe padre viene dichiarato come final, la classe figlia non può sovrascrivere tale metodo. Se una classe viene dichiarata come final, non può essere ereditata.
L'esecuzione del seguente codice genererà un errore:
<?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; } } // Messaggio di errore: Fatal error: Cannot override final method BaseClass::moreTesting() ?>
PHP non chiama automaticamente il metodo costruttore della superclasse nel metodo costruttore della sottoclasse. Per eseguire il metodo costruttore della superclasse, è necessario chiamarlo nel metodo costruttore della sottoclasse. parent::__construct(); .
<?php class BaseClass { function __construct() { print "Classe BaseClass: metodo costruttore" . PHP_EOL; } } class SubClass extends BaseClass { function __construct() { parent::__construct(); // Il metodo costruttore della sottoclasse non può chiamare automaticamente il metodo costruttore della superclasse print "Classe SubClass: metodo costruttore" . PHP_EOL; } } class OtherSubClass extends BaseClass { // Eredita il metodo costruttore di BaseClass } // Chiamata al metodo costruttore di BaseClass $obj = new BaseClass(); // Chiamata ai metodi costruttore di BaseClass e SubClass $obj = new SubClass(); // Chiamata al metodo costruttore di BaseClass $obj = new OtherSubClass(); ?>
Eseguendo il programma sopra, il risultato di output sarà:
Classe BaseClass: metodo costruttore Classe BaseClass: metodo costruttore Classe SubClass: metodo costruttore Classe BaseClass: metodo costruttore