Maison > Article > développement back-end > Compréhension approfondie des fonctionnalités avancées de PHP orientées objet, modèles et pratiques (2)
La classe abstraite ne peut pas être instanciée directement. Les classes abstraites définissent uniquement (ou implémentent partiellement) les méthodes requises par les sous-classes. Les sous-classes peuvent en hériter et rendre la classe abstraite concrète en implémentant ses méthodes abstraites. Vous pouvez définir une classe abstraite à l’aide d’un mot-clé abstrait. Dans la plupart des cas, les classes abstraites contiennent au moins une méthode abstraite. Les méthodes abstraites sont déclarées avec le mot-clé abstract et ne peuvent pas avoir de contenu spécifique.
abstract class ShopProductWriter{ protected $products = array(); public function addProduct(ShopProduct $shopProduct) { $this->products[] = $shopProduct; } abstract public function write();}
Après avoir créé une méthode abstraite, assurez-vous que la méthode est implémentée dans toutes les sous-classes, mais les détails de l'implémentation ne peuvent pas encore être déterminés. Chaque sous-classe doit implémenter toutes les méthodes abstraites de la classe abstraite ou se déclarer comme méthodes abstraites. La classe étendue n'est pas seulement responsable de la simple implémentation des méthodes dans la classe abstraite, mais doit également redéclarer les méthodes. Le contrôle d'accès d'une nouvelle méthode d'implémentation ne peut pas être plus strict que le contrôle d'accès d'une méthode abstraite. Le nombre de paramètres de la nouvelle méthode d'implémentation doit être le même que le nombre de paramètres de la méthode abstraite, et les indications de type correspondantes doivent être régénérées.
class XmlProductWriter extends ShopProductWriter{ public function write() { $str='<?xml version="1.0" encoding="UTF-8"?>'."\n"; $str.="<products>\n"; foreach ($this->products as $shopProduct) { $str.="\t<product title=\"{$shopProduct->getTitle()}\">\n"; $str.="\t\t<summary>\n"; $str.="\t\t{$shopProduct->getSummaryLine()}\n"; $str.="\t\t</summary>\n"; $str.="\t</product>\n"; } $str.="</products>\n"; print $str; } }class TextProductWriter extends ShopProductWriter{ public function write() { $str="PRODUCTS:\n"; foreach ($this->products as $shopProduct) { $str.=$shopProduct->getSummaryLine()."\n"; } print $str; } }
Les classes abstraites fournissent des normes d'implémentation spécifiques, tandis que les interfaces sont de purs modèles. Les interfaces ne peuvent définir que des fonctions, pas le contenu de l'implémentation. Les interfaces peuvent être déclarées avec le mot-clé interface. Les interfaces peuvent contenir des déclarations de propriété et de méthode , mais le corps de la méthode est vide.
interface Chargeable{ public function getPrice();}
Toute classe qui implémente une interface doit implémenter toutes les méthodes définies dans l'interface, sinon la classe doit être déclarée abstraite. Une classe peut implémenter une interface en utilisant le mot-cléimplémenter dans sa déclaration.
class ShopProduct implements Chargeable { //... function getPrice() { return ($this->getPrice-$this->discount); } //...}
La classe ShopProduct possède déjà une méthode getPrice(), est-il donc toujours utile d'implémenter l'interface Chargeable ? La réponse est oui, à cause des types. Une classe qui implémente une interface accepte le type de la classe dont elle hérite et l'interface qu'elle implémente.
N'importe quelle classe peut implémenter une interface, et les interfaces peuvent connecter efficacement des types non liés. Une classe peut hériter d'une classe parent et implémenter n'importe quel nombre d'interfaces en même temps. La clause extends précède la clause Implements.
class Consultancy extends TimedService implements Bookable, Chargeable{//...}
Le signe le plus évident de cette fonctionnalité est le nouveau mot-clé static. static est similaire à self, mais il fait référence à la classe appelée plutôt qu'à la classe contenant. Dans ce cas, cela signifie que l'appel à Document::create() générera un nouvel objet Document, plutôt que d'essayer d'instancier un objet DomainObject.
abstract class DomainObject{ public static function create() { return new static(); } }class User extends DomainObject{ }class Document extends DomainObject{} print_r(Document::create());//输出为Document Object// (// )
Le mot-clé static peut être utilisé non seulement pour l'instanciation. Comme self et parent, static peut également être utilisé comme identifiant pour les appels de méthodes statiques, même à partir de contextes non statiques.
abstract class DomainObject{ private $group; public function construct() { $this->group=static::getGroup(); } public static function create() { return new static(); } static function getGroup(){ return "default"; } }class User extends DomainObject{ }class Document extends DomainObject{ static function getGroup(){ return "document"; } }class SpreadSheet extends Document{} print_r(User::create()); print_r(SpreadSheet::create());//输出为User Object// (// [group:DomainObject:private]=>default // )// SpreadSheet Object// (// [group:DomainObject:private]=>document// )
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!