带有/ Common方法的PHP抽象类:如何调用

时间:2013-09-13 20:48:09

标签: php oop abstract-class static-methods

我对在抽象类中调用常用方法的正确方法感到困惑。使用以下代码:

abstract class Transaction {

    abstract public function process();
    abstract public function set_status();

    protected function get_valid_statuses() {
        return array(
            'pending',
            'approved'
        );
    }

}

class Purchase extends Transaction {

     public function process() {
     }

     public function set_status( $status ) {

          //check against valid statuses
          $valid = Transaction::get_valid_statuses();

          .......

     }

}

显然这段代码远未完成,但应该足以满足这个例子。我想知道为什么会这样,因为我已经测试了它。在我的Purchase类中,当使用set_status方法时,我使用通常用于静态方法的Scope Resolution Operator调用get_valid_statuses()方法。我会假设使用以下方法调用该方法:

$valid = Transaction->get_valid_statuses();

但我想这不会起作用,因为该类实际上从未实例化过。有人可以提供一些澄清。我无法从关于抽象类或范围解析运算符的PHP文档中找到理解。

谢谢!

4 个答案:

答案 0 :(得分:1)

启用错误报告,您会看到严格错误:

  

非静态方法不应该静态调用Transaction :: get_valid_statuses()

所有5.x php版本中都存在此错误 - 因此它出于向后兼容性原因而起作用。回到php4的黑暗时代,没有办法在类中声明静态方法,因此所有方法都被简单地声明为function foo(){ }

您可以了解静态方法here。简单来说,在调用此方法之前不需要实例化类(并且由于abstract关键字而无法实例化它),但您可以使用类名和范围解析运算符来调用它。

这也有效,因为此方法中没有对当前对象($this)的引用。如果您使用$this更改此方法主体以引用其某个属性/方法,则会以致命错误结束。

答案 1 :(得分:0)

抽象类无法实例化,但方法(非抽象)可以作为静态方法调用 无论如何,这是非常糟糕的代码风格 - 请考虑不使用它。

答案 2 :(得分:0)

该方法不是静态的,因此不应使用静态方法运算符(::)。另外因为Purchase继承了抽象类,它会自动获取所有方法,可以使用$this来使用:

$valid = $this->get_valid_statuses();

答案 3 :(得分:0)

使用::运算符(作用域解析运算符)并不总是触发STATIC方法调用。

在你的情况下,确实如此。您正在使用类名。但是有些特殊关键字不会触发静态调用:selfparentstatic

除此之外,还有一个变量引用当前的自己的对象:$this

因此,无论何时继承一个带有自己方法的类,您都可以像对待当前类一样对待它们,并调用$this->get_valid_statuses()。这会以降序动态检查当前类或任何父类或父父类中是否存在该函数,并调用找到的第一个函数。

如果您想确保调用父类的功能,请使用parent::get_valid_statuses()。如果要确保调用CURRENT类的方法,请使用self::get_valid_statuses()

static关键字在继承类中的静态方法时起着重要作用 - 但是因为静态方法通常比帮助你更邪恶,所以我只想指向manual

继承课时该怎么办?这取决于。 $this有效。它还允许覆盖当前类中的get_valid_statuses()并扩展它。

如果您的parent::get_valid_statuses()类覆盖Purchase并希望从父类获取状态,则应该只调用{p> get_valid_statuses()。在这种情况下,您无法调用$this->get_valid_statuses(),因为这将再次调用同一类中的方法,从而导致永无止境的循环。因此,parent::$this->是最常用的前缀。