26

我不是面向对象编程的专家,我有一个愚蠢的问题:

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');

我已经对其进行了测试,并且它可以正常工作,没有任何错误或通知等,但是这样做是否正确?

4

3 回答 3

17

正如 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显式调用您要调用的静态方法。甚至最好不要使用静态方法,因为它们会使您的代码不可测试

于 2012-10-13T16:48:10.417 回答
4

如果您的方法不使用$this且不访问静态属性,则没有区别。

使用箭头运算符 -> 无法通过对象访问静态属性。

$this 在声明为静态的方法中不可用。

但是,您应该始终使用::调用静态方法,即使通过 php 让您在实例上调用它。

于 2012-10-13T15:17:15.993 回答
3

最好以这种方式调用它以避免 E_STRICT在某些版本的 PHP 上

$bar = test::doSomething('Sandwich');

来自 PHP 文档

使用箭头运算符 -> 无法通过对象访问静态属性。静态调用非静态方法会生成 E_STRICT 级别的警告。

将类属性或方法声明为静态使它们无需实例化即可访问。声明为静态的属性不能用实例化的类对象访问(尽管静态方法可以)。

于 2012-10-13T15:13:38.097 回答