Home > Article > Backend Development > In-depth understanding of PHP object-oriented, patterns and practices-advanced features (2)
Abstract classes cannot be instantiated directly. Abstract classes only define (or partially implement) the methods required by subclasses. Subclasses can inherit it and make the abstract class concrete by implementing its abstract methods. You can define an abstract class using abstract keyword. In most cases, abstract classes contain at least one abstract method. Abstract methods are declared with the abstract keyword and cannot have specific content.
abstract class ShopProductWriter{ protected $products = array(); public function addProduct(ShopProduct $shopProduct) { $this->products[] = $shopProduct; } abstract public function write();}
After creating an abstract method, make sure that the method is implemented in all subclasses, but the implementation details can not be determined first. Each subclass must implement all abstract methods in the abstract class, or declare themselves as abstract methods. The extended class is not only responsible for simply implementing the methods in the abstract class, but must also redeclare the methods. The access control of the new implementation method cannot be stricter than the access control of the abstract method. The number of parameters of the new implementation method should be the same as the number of parameters of the abstract method, and the corresponding type hints should be regenerated.
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; } }
Abstract classes provide specific implementation standards, while interfaces are pure templates. Interfaces can only define functions, not implementation content. Interfaces can be declared with the keyword interface. An interface can contain property and method declarations, but the method body is empty.
interface Chargeable{ public function getPrice();}
Any class that implements an interface must implement all methods defined in the interface, otherwise the class must be declared abstract. A class can implement an interface using the implement keyword in its declaration.
class ShopProduct implements Chargeable { //... function getPrice() { return ($this->getPrice-$this->discount); } //...}
The ShopProduct class already has a getPrice() method, so is it still useful to implement the Chargeable interface? The answer is yes, because of types. A class that implements an interface accepts the type of the class it inherits and the interface it implements.
Any class can implement an interface, and the interface can effectively connect unrelated types. A class can inherit a parent class and implement any number of interfaces at the same time. The extends clause comes before the implements clause.
class Consultancy extends TimedService implements Bookable, Chargeable{//...}
The most obvious sign of this feature is the new keyword static. static is similar to self, but it refers to the class being called rather than the containing class. In this case, what it means is that calling Document::create() will generate a new Document object, rather than trying to instantiate a DomainObject object.
abstract class DomainObject{ public static function create() { return new static(); } }class User extends DomainObject{ }class Document extends DomainObject{} print_r(Document::create());//输出为Document Object// (// )
The static keyword can be used not only for instantiation. Like self and parent, static can also be used as an identifier for static method calls, even from non-static contexts.
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// )
The above is the detailed content of In-depth understanding of PHP object-oriented, patterns and practices-advanced features (2). For more information, please follow other related articles on the PHP Chinese website!