class Foo
{
public static $my_static = 'foo';
public function staticValue() {
return self::$my_static;
}
}
class Bar extends Foo
{
public function fooStatic() {
return parent::$my_static;
}
}
print Foo::$my_static . "n";
$foo = new Foo();
print $foo->staticValue() . "n";
print $foo->my_static . "n"; // Undefined "Property" my_static
print $foo::$my_static . "n";
$classname = 'Foo';
print $classname::$my_static . "n"; // As of PHP 5.3.0
print Bar::$my_static . "n";
$bar = new Bar();
print $bar->fooStatic() . "n";
•后期静态绑定:static:: 定义后期静态绑定工作原理是存储了上一个“非转发调用”(non-forwarding call)的类名。当进行静态方法调用时,该类名即为明确指定的那个(通常在 :: 运算符左侧部分);当进行非静态方法调用时,即为该对象所属的类。使用 self:: 或者 __CLASS__ 对当前类的静态引用,取决于定义当前方法所在的类;static:: 不再被解析为定义当前方法所在的类,而是在实际运行时计算的,可以用于静态属性和所有方法的调用。
<?php
class A
{
private $proPrivate = "private of A";
protected $proProtected = "protected of A";
public $proPublic = "public of A";
private function foo()
{
echo $this->proPrivate."n";
echo $this->proProtected."n";
echo $this->proPublic."n";
}
public function test()
{
$this->foo();
static::foo();
}
}
class B extends A
{
/* foo() will be copied to B, hence its scope will still be A and
* the call be successful */
}
class C extends A
{
private $proPrivate = "private of C";
protected $proProtected = "protected of C";
public $proPublic = "public of C";
private function foo()
{
/* original method is replaced; the scope of the new one is C */
echo "I am Cn";
}
public function myFoo()
{
//parent::foo();
$this->foo();
}
}
echo "Class B:n";
$b = new B();
$b->test();
echo "nClass C:n";
$c = new C();
$c->myFoo();
$c->test(); //fails
上例输出结果:
Class B:
private of A
protected of A
public of A
private of A
protected of A
public of A
Class C:
I am C
private of A
protected of C
public of C
Fatal error: Uncaught Error: Call to private method C::foo() from context 'A' in /public/t.php:19 Stack trace: #0 /public/t.php(54): A->test() #1 {main} thrown in /public/t.php on line 19
•继承:官方文档对继承有这样一段描述“当扩展一个类,子类就会继承父类所有公有的和受保护的方法。除非子类覆盖了父类的方法,被继承的方法都会保留其原有功能”,言下之意似乎私有属性和方法不会被继承;然而上例又告诉我们子类拥有与父类一致的属性和方法,继承就是全盘复制,这才能满足我们对继承编程的需求,如果私有的不能继承,子类就必须自行重新定义,在大多数时候没有必要。另外就是可见性问题,父类的私有属性和方法在子类是不可见的。上例还告诉我们对象实际执行的域要考虑可见性、继承、后期静态绑定机制。







