最近看到了PHP面向对象中的延迟静态绑定这块,注意:php5.3之前没有引入延迟静态绑定,所以版本较低的童鞋可能用不了。 
这里我们用一个简单的工厂方法(生成包含类的实例的一种方法)来说明

//定义一个抽象方法作为父类abstract class ParentClass{
    //....}//子类Userclass User extends ParentClass{
    //定义一个静态方法来生成返回一个类实例
    public static function create(){
        return new User();
    }
}//子类Animalclass Animal extends ParentClass{
    public static function create(){
        return new Animal();
    }
}//使用:print_r(User::create());
print_r(Animal::create()); 

//返回:User Object ( ) 
Animal Object ( )12345678910111213141516171819202122232425

从返回结果上看,我们取得了两个子类的实例,说明这个工厂方法正常的工作了。但是,假如我假如Document、Plant等子类呢?我们要重写很多create()方法!这个很烦人!既然create()方法都是类似的,我把这个方法放到父类中怎么样?

abstract class ParentClass{
    //定义一个静态方法来生成返回一个类实例
    public static function create(){
        return new self();
    }
}//子类Userclass User extends ParentClass{
    //...}//子类Animalclass Animal extends ParentClass{
    //...}//使用:print_r(User::create());
print_r(Animal::create()); 

//返回:Fatal error: Cannot instantiate abstract class ParentClass in....123456789101112131415161718192021

返回的结果:不能实例化ParentClass这个抽象类! 
好,我们把抽象abstract去掉:

class ParentClass{
    //定义一个静态方法来生成返回一个类实例
    public static function create(){
        return new self();
    }
}//返回结果:ParentClass Object ( )
ParentClass Object ( )123456789

去掉abstract前后都足以证明:self()调用的是基类本身。 
也就不能把create()放在父类中?错! 
PHP5.3之后引入了延迟静态绑定的概念。该特性最明显的标志就是新关键字static(静态)。static类似于self,但它表示的是被调用的类而不是包含类。现在我们用 static() 替换 self() :

abstract class ParentClass{
    //定义一个静态方法来生成返回一个类实例
    public static function create(){
        return new static();
    }
}//子类Userclass User extends ParentClass{
    //...}//子类Animalclass Animal extends ParentClass{
    //...}//使用:print_r(User::create());
print_r(Animal::create()); 

//返回:User Object ( ) 
Animal Object ( )12345678910111213141516171819202122

我们暂时可以这样理解:self()只能父类中起作用,只会紧跟在所在类中,固定的,而static()灵活性更强,谁调用我,我就是在谁那里起作用,被子类继承下来,那就是指的是子类。在本类中,self()指的是ParentClass,而对于static(),子类User调用我,我就是指User类。当然,通过ParentClass类的对象调用create(),static()指的就是ParentClass类了

关于static关键字,它不仅可以用于实例化所在类,和self和parent一样,static还可以调用类里面的方法:

//这里先用selfclass ParentClass{
    public $order;    //构造函数
    function __construct(){
        $this->order = self::getOrder();//调用本类的getorder()方法
    }    //延迟静态绑定
    public static function create(){
        return new static();
    }    public function getOrder(){
        return "ParentClass";
    }
}class User extends ParentClass{
    //重写getOrder()方法
    public function getOrder(){
        return "User";
    }
}class Animal extends ParentClass{
    //重写getOrder()方法
    public function getOrder(){
        return "Animal";
    }
}//使用:print_r(User::create());
print_r(Animal::create());//返回结果:User Object ( [order] => ParentClass ) 
Animal Object ( [order] => ParentClass )123456789101112131415161718192021222324252627282930313233

结果也说明了,self关键字只能父类中起作用,只会紧跟在所在类中, 
我们把self换成static:

class ParentClass{
    public $order;    //构造函数
    function __construct(){
        $this->order = static::getOrder();//调用本类的getorder()方法
    }    public static function create(){
        return new static();
    }    public function getOrder(){
        return "ParentClass";
    }
}//使用:print_r(User::create());
print_r(Animal::create());//返回结果:User Object ( [order] => User )
Animal Object ( [order] => Animal )1234567891011121314151617181920

看结果,static成功的调用了子类中的getOrder()方法!

现在我比较喜欢拿C#和PHP作对比。。。。 
在这里,我感觉这跟C#中的运行时多态比较相似(多态后面给大家介绍,这里先用了)

//动物类:父类
    public class Animal
    {        public int age;//年龄
        public double weight;//体重
        //吃方法:虚方法
        public virtual string Eat()
        {            return "Animal Eat";
        }        public virtual string Sleep()
        {            return "Animal Sleep";
        }
    }    //狗类:子类
    public class Dog : Animal
    {        //覆写虚方法
        public override string Eat()
        {            return "Dog Eat";
        }        public override string Sleep()
        {            return "Dog Sleep";
        }
    }    public class Bird : Animal
    {        public override string Eat()
        {            return "Bird Eat";
        }        public override string Sleep()
        {            return "Bird Sleep";
        }
    }//使用:Animal al1 = new Dog();
Animal al2 = new Bird();
Console.WriteLine(al1.Sleep());
Console.WriteLine(al2.Sleep());
Console.ReadLine();//输出结果:Dog Sleep
Bird Sleep12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849

假如我把Dog类中的覆写Sleep()方法去掉

public class Dog : Animal
    {        //覆写虚方法
        public override string Eat()
        {            return "Dog Eat";
        }
    }//返回结果:Animal Sleep
Bird Sleep123456789101112

运行时多态(virtual 和 override 关键字):当用子类实例化父类的时候,通过判断对象的类型来决定执行哪个类中的哪个方法,在这里:Animal al1 = new Dog(); 
al1的类型是Animal,然后去Animal类里面找Sleep()方法,但是,当发现Sleep()方法是个虚方法,到Dog()里面看看该方法有没有被覆写,假如被覆写了,调用覆写后的方法,不然调用虚方法。 
这就好比PHP中的延迟静态绑定中的 self 和 static 关键字,假如子类中有覆写(override)父类的虚方法,就相当于使用 static,没有覆写就相当于使用 self。