一、静态属性和方法
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);
}
}
}