0


0

静的クラス継承はPHPで動作しませんか?
abstract class base {
    abstract public function test();
    public function run()
    {
        self::test();
    }
}

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

それは報告します:

_ 致命的なエラー:抽象メソッドbase :: test()を呼び出せません _

しかし、 `son

test()`は機能します。なぜ修正する方法がありますか?

4 Answer


4


もちろん:

_ 致命的なエラー:* abstract *メソッドbase :: test()を呼び出せません _

呼び出すことができるメソッド本体はありません。 run()がhttp://sourcemaking.com/design_patterns/template_method[Template Method]である場合、 self`ではなく $ this`でクラススコープを参照し、$ 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()メソッドはstaticとして宣言されておらず、それでもPHPはrun()を実行しますが、誤った使用方法と見なされ、E_STRICTエラーが発生するため、これは誤りです。 ただし、run()staticを定義すると、 `$ this`を参照できなくなります。これは、静的メソッドがインスタンススコープからではなく、クラススコープから呼び出されるためです。

*編集*私はPHP5.3ソリューションを追加しようとしていましたが、入力中に@erenonがすでにそれを行っていたことがわかりますので、http://php.net/manual/のPHPマニュアルに適切な参照を追加するだけですen / language.oop5.late-static-bindings.php [Late Static Binding]。


4


「self」はレキシカルにスコープされます。つまり、Baseのメソッドで「self」を使用する場合、実行時にこのメソッドをどのように呼び出しても、「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


Abstract methodsには実装がないため、呼び出すことができません。 メソッドが抽象として定義されておらず、実際に実装されている場合は、コードで実行できます。 例えば:

public function test(){
    echo "Hello from base!";
}


1


工場/シングルトンパターンミックス:

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