наследник статического класса не работает в PHP? - PullRequest
0 голосов
/ 10 марта 2010
abstract class base {
    abstract public function test();
    public function run()
    {
        self::test();
    }
}

class son extends base {
    public function test()
    {
        echo 1;
    }
}
son::run();

Сообщает:

Неустранимая ошибка: невозможно вызвать реферат метод базы :: test ()

Но son::test() работает, почему и есть ли способ исправить?

Ответы [ 4 ]

4 голосов
/ 10 марта 2010

Конечно:

Неустранимая ошибка: невозможно вызвать abstract base base :: test ()

У него нет тела метода, который вы могли бы вызвать. Если предполагается, что run () - шаблонный метод , вы ссылаетесь на область действия класса с $this вместо self, а затем создаете экземпляр $ son для вызова run (), например:

abstract class BaseClass {
    abstract public function test();
    public function run()
    {
        $this->test();
    }
}

class Son extends BaseClass {
    public function test()
    {
        echo 1;
    }
}

$son = new Son;
$son->run(); // 1

, что довольно странно, потому что тогда вы могли бы точно так же вызвать test () напрямую.

Также обратите внимание, что в вашем примере

son::run();

неверно, потому что метод run () не объявлен как статический, и хотя PHP выполнит run (), тем не менее, это считается неправильным использованием и вызовет ошибку E_STRICT. Однако, если бы вы определили статическую функцию run (), вы бы больше не могли ссылаться на $this, потому что статический метод вызывается не из области видимости экземпляра, а из области класса.

Редактировать Я собирался добавить решение PHP5.3, но вижу, что @erenon уже делал это, пока я печатал, поэтому я только добавляю соответствующую ссылку в Руководство по PHP для Позднее статическое связывание .

4 голосов
/ 10 марта 2010

«self» имеет лексическую область, то есть если вы используете «self» в методе Base, «self» означает «Base», независимо от того, как вы вызываете этот метод во время выполнения. В php5.3 появился новый тип динамического связывания, которое, как ни странно, называется «статическим». Следующие работы, как и ожидалось в PHP 5.3

abstract class base {
    abstract public static function test();
    static public function run()
    {
        static::test();
    }
}

class son extends base {
    static public function test()
    {
        echo 1;
    }
}
son::run();
1 голос
/ 10 марта 2010

Фабрика / синглтон:

class Base
{
    static private $instance;

    static function getSon() {
        if (null === self::$instance) {
            self::$instance = new Son;();
        }

        return self::$instance;
    }
}

class Son
{
    public function test() {
        echo 1;
    }
}

Base::getSon()->test(); //1
1 голос
/ 10 марта 2010

Абстрактные методы не имеют реализации и поэтому не могут быть вызваны. Если метод не определен как абстрактный и фактически имеет реализацию, то он может быть выполнен вашим кодом. Например:

public function test(){
    echo "Hello from base!";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...