我不是面向对象编程的专业人士,我有一个愚蠢的问题:
class test {
public static function doSomething($arg) {
$foo = 'I ate your ' . $arg;
return $foo;
}
}
因此调用doSomething()
方法的正确方法是test::doSomething('Pizza');
,我是对的吗?
现在,如果我这样称呼会发生什么:
$test = new test;
$bar = $test->doSomething('Sandwich');
我已经对它进行了测试,并且没有任何错误或通知等工作,但这样做是否正确?
答案 0 :(得分:14)
正如Baba已经指出的那样,它会产生E_STRICT
,具体取决于您的配置。
但即使这对你来说没问题,我认为值得一提的是以非静态方式调用静态方法可能导致的一些陷阱。
如果您有类层次结构,如
class A {
public static function sayHello() {
echo "Hello from A!\n";
}
public function sayHelloNonStaticWithSelf() {
return self::sayHello();
}
public function sayHelloNonStaticWithStatic() {
return static::sayHello();
}
}
class B extends A {
public static function sayHello() {
echo "Hello from B!\n";
}
public function callHelloInMultipleDifferentWays() {
A::sayHello();
B::sayHello();
$this->sayHelloNonStaticWithSelf();
$this->sayHelloNonStaticWithStatic();
$this->sayHello();
}
}
$b = new B();
$b->callHelloInMultipleDifferentWays();
这会产生以下输出:
Hello from A!
// A::sayHello() - obvious
Hello from B!
// B::sayHello() - obvious
Hello from A!
// $this->sayHelloNonStaticWithSelf()
// self alweays refers to the class it is used in
Hello from B!
// $this->sayHelloNonStaticWithStatic()
// static always refers to the class it is called from at runtime
Hello from B!
// $this->sayHello() - obvious
如您所见,在混合静态和非静态方法调用和技术时,很容易实现意外行为。
因此,我的建议也是: 使用 Class :: method 显式调用您要调用的静态方法。 或者更好的是不要使用静态方法,因为它们使您的代码不可测试。
答案 1 :(得分:3)
最好用这种方式调用它来避免某些版本的PHP上的E_STRICT
$bar = test::doSomething('Sandwich');
使用箭头操作符 - >无法通过对象访问静态属性。静态调用非静态方法会生成E_STRICT级别警告。
另外
将类属性或方法声明为静态使它们可以访问,而无需实例化类。声明为static的属性无法使用实例化的类对象访问(尽管静态方法可以)。
答案 2 :(得分:3)
如果您的方法不使用$this
并且不访问静态属性,则没有区别。
无法使用箭头操作符 - >通过对象访问静态属性。
$在声明为static的方法中不可用。
但是,您应该始终使用::
来调用静态方法,即使通过php也可以在实例上调用它。