深入PHP面向对象、模式与实践——高级特性(2)
2017-03-18 16:59
821 查看
抽象类
抽象类不能被直接实例化。抽象类只定义(或部分实现)子类需要的方法。子类可以继承它并且通过实现其中的抽象方法,使抽象类具体化。你可以用abstract关键字定义一个抽象类。大多数情况下,抽象类至少包含一个抽象方法。抽象方法用abstract关键字声明,其中不能有具体内容。abstract class ShopProductWriter { protected $products = array(); public function addProduct(ShopProduct $shopProduct) { $this->products[] = $shopProduct; } abstract public function write(); }
创建抽象方法后,要确保所有的子类中都实现了该方法,但实现的细节可以先不确定。每个子类都必须实现抽象类中的所有抽象方法,或者把它们自身也声明为抽象方法。扩展类不仅仅负责简单实现抽象类中的方法,还必须重新声明方法。新的实现方法的访问控制不能比抽象方法的访问控制更严格。新的实现方法的参数个数应该和抽象方法的参数个数一样,重新生成对应的类型提示。
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; } }
接口
抽象类提供了具体的实现的标准,而接口(interface)则是纯粹的模板。接口只能定义功能,而不包含实现的内容。接口可用关键字interface来声明。接口可以包含属性和方法声明,但是方法体为空。interface Chargeable{ public function getPrice(); }
任何实现接口的类都要实现接口中所定义的所有方法,否则该类必须声明为abstract。一个类可以在声明中使用implement关键字来实现某个接口。
class ShopProduct implements Chargeable { //... function getPrice() { return ($this->getPrice-$this->discount); } //... }
ShopProduct类已经有一个getPrice()方法,那么实现Chargeable接口还有用吗?答案是肯定的,因为类型。实现接口的类接受了它继承的类及实现的接口的类型。
任何类都可以实现接口,接口可以有效地将不相关的类型联结起来。一个类可以同时继承一个父类和实现任意个接口。extends子句一个在implements子句之前。
class Consultancy extends TimedService implements Bookable, Chargeable{ //... }
延迟静态绑定:static关键字
该特性最明显的标志就是新关键字static。static类似于self,但它指的是被调用的类而不是包含类。在本例中,它的意思是调用Document::create()将生成一个新的Document对象,而不是试图实例化一个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 // ( // )
static关键字不仅仅可以用于实例化。和self和parent一样,static还可以作为静态方法调用的标识符,甚至是从非静态上下文中调用
4000
。
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 // )
相关文章推荐
- 深入PHP面向对象、模式与实践——高级特性(3)
- 深入PHP面向对象、模式与实践——高级特性(5)
- 深入PHP面向对象、模式与实践——高级特性(1)
- 深入PHP面向对象、模式与实践——高级特性(6)
- 深入PHP面向对象、模式与实践——高级特性(4)
- 深入PHP面向对象、模式与实践——让面向对象编程更加灵活的模式(3)
- 深入PHP面向对象、模式与实践——组合模式
- PHP对象、模式与实践之高级特性分析
- php面向对象书籍推荐:深入PHP:面向对象、模式与实践(第3版)
- 深入PHP面向对象、模式与实践——执行及描述任务(3)
- 深入PHP面向对象、模式与实践——生成对象(2)
- 深入PHP面向对象、模式与实践——对象
- 深入PHP面向对象、模式与实践——对象工具(3)
- 《PHP对象、模式与实践》之高级特性
- 深入PHP面向对象、模式与实践——执行及描述任务(2)
- 深入php面向对象、模式与实践
- 深入PHP面向对象、模式与实践——生成对象(3)
- 深入php面向对象、模式与实践
- 深入PHP面向对象、模式与实践——执行及描述任务(1)
- 深入PHP面向对象、模式与实践——对象与设计