2011-09-14 20 views
2
class A{ 
    private static $instance; 

    public static function getInstance(){ 

    if(!(self::$instance instanceof self)) 
     self::$instance = new self(); 

    return self::$instance; 
    } 

    public function doStuff(){ 
    echo 'stuff'; 
    } 


} 

class B extends A{ 
    public function doStuff(){ 
    echo 'other stuff'; 
    } 
} 

A::getInstance()->doStuff(); // prints "stuff" 

B::getInstance()->doStuff(); // prints "stuff" instead of 'other stuff'; 

私は間違って何をしていますか?PHPでクラスを拡張する

なぜクラスBはその機能を実行しませんか?

答えて

4

ルックでそれを呼んで、クラスAにはまだありません:Aに、ではないと呼ばれていたクラスに

if(!(self::$instance instanceof self)) 
     self::$instance = new self(); 

すべてのものをselfのポイント。 PHP 5.3には、"late static binding"というものが導入されています。コードが存在するクラスではなく、呼び出されたクラスを指すことができます。あなたはstaticキーワードを使用する必要があります:あなたは、少なくともPHP 5.3を持っていない場合

class A{ 
    protected static $instance; // converted to protected so B can inherit 

    public static function getInstance(){ 
    if(!(static::$instance instanceof static)) 
     static::$instance = new static(); // use B::$instance to store an instance of B 

    return static::$instance; 
    } 

    public function doStuff(){ 
    echo 'stuff'; 
    } 
} 

残念ながら、これは失敗します。

4

クラスAのgetInstanceでselfを使用しているので、クラスBでgetInstanceを呼び出すと、自分がまだクラスA ...を参照していると思います。

だから、基本的に、あなたはA.

1

自己の2つのインスタンスにdoStuff()を呼んでいる::関係なく、あなたがgetInstanceのコードで

2

PHP(あなたが使用しているバージョンでは)彼らはで定義されたクラスに静的関数をバインドするためです。

のでB::getInstance()が、私はこれがされていると考えているクラスA

のオブジェクトを返します。 PHP 5.3以降で変更されました。多くの人にとって大きな苦痛の原因となりました(自分自身も含めて!)。

これに関するいくつかの詳細がアップである: http://php.net/manual/en/language.oop5.late-static-bindings.php

2

のgetInstance(次のコードを試してみてください)

public static function getInstance(){ 

    if(!self::$instance) 
    { 
     $curClass = get_called_class(); 
     self::$instance = new $curClass(); 
    } 

    return self::$instance; 
    } 
関連する問題