PHP对象高级特性

一、静态属性和方法

class StaticExample{
	static public $aNum = 0;
	static public function sayHello(){
		self::$aNum++;
		echo "hello" . self::$aNum;
	}
}
echo StaticExample::$aNum;
StaticExample::sayHello();

1、静态方法是以类作为作用域的函数。静态方法不能访问这个类的普通属性,但可以访问静态属性。

2、只有在使用parent关键字时。才能对一个非静态方法进行静态式调用。(使用::)

3、不能在对象中调用静态方法,也不能在静态方法中使用伪变量$this

二、常量属性

class ConstExample{
	const A = 0;
}
$a = new ConstExample();
echo $a::A;
echo ConstExample::A;

1、常量不像常规属性使用$开头,一般使用大写字母来命名常量

2、常量属性只包含基本数据类型的值,不能将一个对象指派给常量

三、抽象类

abstract class AbstractExample{
	protected $array = array();

	public function addArray(Example $example){
		$this->array = $example;
	}

	abstract public function write();
}

1、抽象类一般都包含一个抽象方法,抽象方法用abstract关键字声明,其中不能有具体内容

2、抽象类的每个子类都必须实现抽象类的所有抽象方法,或者把他们自身也声明为抽象方法

四、接口

interface InterfaceExample{
	public function sayHello();
}

1、接口只能定义功能,而不包含实现内容。接口可以包含属性和方法声明,但是方法体为空

2、任何实现接口的类都必须实现接口中所定义的所有方法,否则该类必须声明为abstract

3、实现接口的类接受了它继承的类及其实现的接口类型 如果有一个类实现了接口InterfaceExample,那么该类的类型也属于InterfaceExample

4、一个类可以同时继承一个父类和实现任意个接口

五、延迟静态绑定:static关键字

//实例一
abstract class DomainObject{
	public static function create(){
		return new self();
	}
}
class User extends DomainObject{}
class Document extends DomainObject{}
Document::create();
//Fatal error: Cannot instantiate abstract class DomainObject in D:\phpStudy\WWW\highLevel.php on line 89
//实例二
abstract class DomainObject{
	public static function create(){
		return new static();
	}
}
class User extends DomainObject{}
class Document extends DomainObject{}
var_dump(Document::create());
//object(Document)#2 (0) {}

/**
 * 注:
 * 1、self被解析为定义create()的DomainObject,而不是解析为调用self的Document类。static类似与self,但它指的是被调用的类而不是包含类
 */

//实例三
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{}
var_dump(User::create());
var_dump(SpreadSheet::create());
//object(User)#2 (1) { ["group":"DomainObject":private]=> string(7) "default" } object(SpreadSheet)#2 (1) { ["group":"DomainObject":private]=> string(8) "document" } 

//实例四
abstract class DomainObject{
	private $group;
	public function __construct(){
		$this->group = self::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{}
var_dump(User::create());
var_dump(SpreadSheet::create());
//object(User)#2 (1) { ["group":"DomainObject":private]=> string(7) "default" } object(SpreadSheet)#2 (1) { ["group":"DomainObject":private]=> string(7) "default" } 

/**
 * 注:
 * 1、static关键字不仅仅可以用于实例化,和self和parent一样,static还可以作为静态方法调用的标志符,甚至是从非静态上下文调用
 */

六、Final类和方法

1、final关键字可以终止类的继承,final类不能有子类,final方法不能被覆写

七、使用拦截器

class PersonWrite{
	function writeName(Person $p){
		print $p->getName()."\n";
	}
	function writeAge(Person $p){
		print $p->getAge()."\n";
	}
}
class Person{
	private $write;
	function __construct(PersonWrite $write){
		$this->write = $write;
	}
	function __call($methodName, $arge){
		if(method_exists($this->write, $methodName)){
			return $this->write->$methodName($this);
		}
	}
	function getName(){return "Bob";}
	function getAge(){return 44;}
}
$person = new Person(new PersonWrite());
$person->writeName();
1、__get($property)                 访问为定义的属性时被调用
2、__set($property, $value)         给未定义的属性赋值时被调用
3、__isset($property)               对未定义的属性调用isset()时被调用
4、__unset($property)               对未定义的属性调用unset()时被调用
5、__call($method, $arg_array)      调用未定义的方法时被调用

八、析构方法

对象从内存中删除之前自动调用,你可以利用这个方法进行最后必要的清理工作

九、使用__clone()复制对象

//PHP5以后,对象的赋值和传递都是通过引用进行的
//浅复制
class Account{}
class CloneExample1{
	private $account;
	function __construct(){
		$account = new Account();
	}
}
$clone1 = new CloneExample1();
$clone2 = clone $clone1;
//这样的浅复制可以保证所有基本数据类型的竖向被完全复制。在复制对象属性时只复制引用,并不复制引用的对象
//深复制
class Account{}
class CloneExample2{
	private $account;
	function __construct(){
		$account = new Account();
	}
	function __clone(){
		$this->account = clone $this->account;
	}
}
$clone1 = new CloneExample2();
$clone2 = clone $clone1;

十、回调、匿名函数和闭包

class Product{
	public $name;
	public $price;
	function __construct($name, $price){
		$this->name = $name;
		$this->price = $price;
	}
}
class ProcessSale{
	private $callbacks;
	function registerCallback($callback){
		if(!is_callable($callback)){
			throw new Exception("callback not callable");
		}
		$this->callbacks[] = $callback;
	}
	function sale($product){
		print "{$product->name} : processing \n";
		foreach ($this->callbacks as $callback) {
			call_user_func($callback, $product);
		}
	}
}




猜你喜欢

转载自blog.csdn.net/liu2446426696/article/details/76769220