时间:2021-07-01 10:21:17 帮助过:5人阅读
抽象类不能被直接实例化。抽象类只定义(或部分实现)子类需要的方法。子类可以继承它并且通过实现其中的抽象方法,使抽象类具体化。你可以用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类似于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还可以作为静态方法调用的标识符,甚至是从非静态上下文中调用。
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面向对象、模式与实践-高级特性(二)的详细内容,更多请关注Gxl网其它相关文章!