21,886
社区成员
发帖
与我相关
我的任务
分享
<?php
class cls{
public static function print_str(){
echo 'OK';
}
}
cls::print_str();
?>
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
self::who();
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}
B::test();
手册中指的应该是如下情况,如果父类中的方法有使用self::相互调用的情况,那么子类继承下来时,self::并不会改变环境为当前子类,而还是会去调用父类的方法。那么按照手册中说的。将父类中所有self关键字替换为static::,就可以达到目的了。
class a {
public function print_class_name() {
echo __CLASS__;
}
}
class b extends a {}
$b = new b();
$b->print_class_name();
输出还是a
所以应该和是否静态无关,不过我之前确实不知道,继承下来的方法并不能改变当初的环境。查了一下,这个并非是因为T1没有继承T的方法,而是__CLASS__取值的早绑定和晚绑定造成的。从表面上来看,它也确实是"继承"下来了这个方法,只不过对于当前环境不是像我想的那样。
php手册中有指出在5.3之后,加入了一个关键字来解决这个问题。
http://php.net/manual/zh/language.oop5.late-static-bindings.php
class a {
public static function print_class_name() {
echo __CLASS__;
}
public static function call_foo(){
static::print_class_name();
}
}
class b extends a {}
b::call_foo();
但我按照里面的代码试验,还是只能输出父类名称。不知是否与我的php版本有关,我是php5.4.10。
除非在子类中覆写父类的那个方法,才能调用到子类的方法。
class a {
public static function print_class_name() {
echo __CLASS__;
}
}
class b extends a {
public static function print_class_name() {
echo __CLASS__;
}
}
b::print_class_name();
这样输出就是b了。
然后我尝试在ruby中试验:
#encoding:utf-8
class A_class
def foo
puts self::class
end
end
class B_class < A_class
end
b = B_class.new
b.foo
结果输出B_class,可见,ruby是晚绑定的。class T {
static function f() {
echo __CLASS__;
}
}
class T1 extends T {
}
T1::f();