2013-06-10 33 views
5

PHP Inheritance ile ilgili bir sorun yaşıyorum.PHP tekil ve kalıtım

Bu temel sınıf var, Singleton:

namespace My_Namespace; 

abstract class Singleton { 
    protected static $instance = null; 

    static function get() { 
     if (null == static::$instance) { 
      static::$instance = new static; 
     } 
     return static::$instance; 
    } 

    private function __construct() { 

    } 
} 

Ben, B, C, D, onları bir çağrı, o Singleton sınıfını miras sınıfların bir grup var İşte anlaşma. Bunlardan biri şu şekildedir: Şimdi

namespace My_Namespace; 

class A extends Singleton { 

    protected function __construct() { 

     B::get(); 

     if (some_condition()) { 
      C::get(); 
     } 
     else { 
      D::get(); 
     } 
    } 
} 

, Herşeyin haddeleme almak için bir A::get() yok. A'nın kurucusu beklendiği gibi çağrılır. Daha sonra, B'nin kurucusu tekrar sorun olmadan çağrılır. Şimdi garipleşiyor. Bir kere C::get() çağrıldığında, static::$instance'u zaten B sınıfı nesnesi olarak tanır ve C'yi hiç oluşturmaz. Biliyorum ki, ben onları zincirleme, ben __construct B C::get veya D::get çalışır, ama bu benim amaçlar için en uygun değil. Bunların aynı kapsamda olmasından mı kaynaklanıyor? Eğer öyleyse, bunun etrafında herhangi bir yolu var mı? Bunu pratik amaçtan ziyade daha çok merak ediyorum. Biliyorum ki, her birinin tekil desenini kolayca uygulayabiliyorum. Yani, herhangi bir fikir? Teşekkürler!

P.S. Lütfen 'singletonlar kötülük olsun ve cehennemde yanıyor olmalısınız'. Bunu gayet iyi biliyorum.

+1

+1 için "hayır ... cehennemde yanar yorum yap" – phpisuber01

+1

Devralınan sınıfların içine örnek eklenebilmesi için statik bir özelliğe gereksinim duyduğuna inanıyorum ... böylece alt sınıflara "korumalı statik $ instance = null;" ekleyin . – Orangepill

+0

@Orangepill var. Bu çizgiyi ekledim ve hepsi beklendiği gibi çalışıyor. “AMAÇ:” Bu tek kişilik sınıf ve miras kalımını işe yaramaz kılıyor olsa da ... Bu fikir, o sınıfta tekil işlevselliğe sahip olmaktı. Bu mümkün mü? –

cevap

2

Not: static::$instance = new static, (sizin durumunuzda) A yapıcısını çağırır.

Çözümünüzde, alt sınıflarınızdaki örneğiniz için statik bir özelliğe ihtiyacınız olacaktır.

Sadece onlara

protected static $instance = null; 

ekleyin ve sorun çıkmaması gerekir.

+0

Neden ilk iki kez çalışıyor? Nasıl olur da aynı kapsamda değilsem, A :: get() 've' B :: get() 'gibi uygun örnekleri oluşturur. fakat C :: get() 'e girer girmez, B :: get' için kullandığı şeye geri döner? Bu herhangi bir anlam ifade eder mi? –

+1

İlk iki kez işe yaramaz, işe yarıyor İlk kez, A :: get() 'dediğinizde, sonra 'A' yapıcısı çağrılır. Bu, ** base sınıfından gelen" $ instance "dan B :: get()' yi çağırır. * (ayarlanmışsa ilk kez) ayarlayın. Ve şimdi :: statik $ instance' 'boş == denetler, ama bu, C ::') (get 'aramak istediğiniz edilir şimdi' $ instance' ** (A) sınıfı zaten bir nesnedir. – bpoiss

+0

Açıklamaların ne kadar kolay olduğunu anlamak için biraz zaman harcadım. Statik :: $ instance = new static'de, yapıcı, gerçek $ instance değişkenine herhangi bir şey atamadan önce, henüz geri dönmediği için, başka bir yapıcıyı çağıran çağrılır. Aptal ben. Cevap için teşekkürler. –

1

devralınan sınıfların statik özellikler bunu yaşamak için bir ev sağlamak zorunda taban sınıflardan farklı istiyorsanız statik özellikleri ile ilgili.

sadece tanımlamak sorunu çözmek için

protected static $instance = null; 
Türetilmiş sınıfınızda

. Aksi takdirde temel sınıf 'özelliğini kullanacaktır.