虽然您可以在没有实例的情况下调用非静态方法,但这会触发E_STRICT
警告。静态方法的全部意义在于访问类上的静态变量,但许多人将其用作对实用函数进行逻辑分组的一种方式,而不是定义一堆全局函数。
当您使用类的名称调用静态方法时,例如Class::foo()
,没有实例,因此没有多态性。直接调用foo
定义的 by 。Class
如果它没有定义这样的方法,则搜索它的超类,直到找到一个。
class Parent {
static function foo() {
echo "Parent::foo";
}
static function bar() {
echo "Parent::bar";
}
}
class Child extends Parent {
static function foo() {
echo "Child::foo";
}
}
Parent::foo(); // Parent::foo
Parent::bar(); // Parent::bar
Child::foo(); // Child::foo
Child::bar(); // Parent::bar
self
当您使用类方法中的关键字调用静态方法时,例如self::foo()
,它的工作方式就像您要替换self
为包含调用代码的类的名称一样。
class Parent {
static function foo() {
echo "Parent::foo";
}
static function callFoo() {
self::foo(); // equivalent to Parent::foo()
}
}
class Child extends Parent {
static function foo() {
echo "Child::foo";
}
}
Parent::callFoo(); // Parent::foo
Child::callFoo(); // Parent::foo
当您使用static
类方法中的关键字调用静态方法时,例如static::foo()
,您正在调用后期静态绑定。它不是在当前类中开始搜索foo
,而是从当前类上下文开始,即最初静态引用的类。
class Parent {
static function foo() {
echo "Parent::foo";
}
static function callFoo() {
static::foo(); // late static binding
}
}
class Child extends Parent {
static function foo() {
echo "Child::foo";
}
static function callParentCallFoo() {
Parent::callFoo(); // resets static context to Parent
}
}
Parent::callFoo(); // Parent::foo
Child::callFoo(); // Child::foo
Child::callParentCallFoo(); // Parent::foo
后期静态绑定与静态类属性类似,但该属性必须在子类本身中定义。将新属性分配给类(例如Child::$foo = 'foo'
)不会使其可用于父级的 LSB。