OOP/PHP5: Sınıf B Sınıf A arama - ya da, atı atlama yapma

4 Cevap php

Eğer iki sınıf, A ve B. tersi kez hem sınıfları örneğini ve daha sonra A sınıfı B sınıfı çağrı yöntemleri, izin ve mümkün mü demek?

Bu iki nokta üst üste (::) kullanılarak yapılabilir ...... ancak o zaman yöntem statik olur - bir dezavantaj bu? (Aşağıdaki örneğe bakınız)

Diğer yollarla yapılabilir mi? Arayüzleri ile?

Bu kod Benim yapmaya çalıştığım şey gösterir:

class A {
  function horse() {
    echo "horse";
  }
}

class B {
  function jump() {
    // $A = new A; ... don't want to add this in each method.
    $A->horse();  // Fails - $A is out of scope ($A = new A;).
    // A::horse();  // Old code style - works.
    // $this->horse();  // Works if you extend A - not self-documenting.
    // $this->A->horse();  // Fails - out of scope.
  }
}

$A = new A;
$B = new B; // Better to use "$B = new B($A);" ?
$B->jump(); // fails - the horse is sleeping.

Edit

Well, I am building a MVC-framework ve I want to re-use code from other classes. Some real-world examples:

  • Bir veritabanı nesnesi sınıfları karşısında geçirilen ediliyor.
  • / manipule URL'leri yaratan bir "url" class - diğer sınıfları tarafından kullanılan.
  • ... Ve bir kod örneği:

    class url {
        function anchor($url,$name) {
            return "<a href="{$url}\">{$name}</a>";
        }
    }
    
    class someclass {
        function text($str,$url) {
            return "{$str}. " . $url->anchor($url,"Read more...");
        }
    }
    

4 Cevap

Ben ne için soruyorsun böyle A ve B ikisi de uzatabilir çoklu miras olduğunu düşünüyorum

<?php
class C extends A,B {

//...

}

Bu ancak iyi nedenler (aslında bunu çözmek için çalışıyor daha fazla sorun yaratıyor) için PHP not mümkündür.

Orada çoklu kalıtım için herhangi bir alternatif olduğunu ve cevap Şimdi eğer kendinize sorabilirsiniz: Evet, var! Bakmak strategy pattern (Benjamin Ortuzar da işaret ettiği gibi).

UPDATE:

Ben sadece senin soruyu ikinci kez okumak ve size sadece bir kez böyle bir sınıfın bir örneğini olanak sağlayan, singleton pattern arıyor olabileceğini düşündüm:

class A
{

    protected static $_instance;

    protected function __construct() //prohibit creating instances from outside
    { }

    public static function getInstance() 
    {
      if( self::$_instance === NULL ) {
        self::$_instance = new self();
      }
      return self::$_instance;
    }
}

$instance = A::getInstance();

Şimdi A::getInstance() her zaman B kullanabileceğiniz bir aynı örneğini verir ve dinamik fonksiyonları avantajları ve statik fonksiyonları erişilebilirlik hem de olabilir.

UPDATE2:

Birden fazla db-bağlantısı olabilir eğer veritabanı registry içine aittir. Eğer her zaman tek db-bağlantısına ihtiyacınız olacak kesinlikle emin iseniz siz de bunu bir tek yapabilir.

URL yardımcı için ben eğer statik bir sınıf yazıyorum öneririm ve gerçekten daha önce belirtildiği gibi, bu bir tek dinamik bir marka olması gerekiyor.

Ben bu işe gerektiğini düşünüyorum:

$B = new B();
$B->jump();

Ancak http://www.php.net/manual/en/language.oop5.php bakın / okumalısınız

Eğer farklı bir php dosyasından erişiyor eğer Tabii ki sınıfını içe aktarmanız gerekir. Eğer nesne iseniz ve size kullanmanız gereken yöntemi diyorlar

$this->jump();

Ben fabrika ve strateji desen hakkında okuma öneririz. Bu muhteşem kitabın birinci bölümünde bu konuda daha fazla bilgi edinebilirsiniz. link text

Ben bütün kitap okuma tavsiye ederim.

Belki de (sadece tahmin) gibi bir şey arıyorsanız aggregation in COM:

Aggregation is the object reuse mechanism in which the outer object exposes interfaces from the inner object as if they were implemented on the outer object itself.

Sen "magic method" __call böyle bir şeyi inşa edebilirsiniz. Nesnenin bağlamında bu yöntem çağrılabilir yöntem denir her zaman çağrılır ve kod bu çağrı ile ne karar verebilirsiniz. Örneğin "Dış" nesnesinin bir özelliği olarak saklanan başka bir nesne bu isimde bir yöntem sunar ve iç nesnenin yöntem diyorsun daha eğer test edebilirsiniz.

class Foo {
  protected $inner = null;
  public function __construct($inner=null) {
    if ( is_null($inner) && !is_object($inner) ) {
      throw new Exception('...');
    }
    $this->inner = $inner;
  }

  public function __call($name, $arguments) {
    // also check http://uk.php.net/is_callable
    if ( !is_null($this->inner) && method_exists($this->inner, $name) ) {
      return call_user_func_array( array($this->inner, $name), $arguments);
    }
    else {
      // add some error handler here
      throw new Exception('...');
    }
  }

  function jump() {
    $this->horse();
    echo " jumps";
  }
}

class Bar {
  function horse() {
    echo "horse";
  }
}

$foo = new Foo(new Bar);
$foo->jump();

Bu çalışıyor. Ama ben sadece oldukça özel durumlar için böyle bir şey tavsiye ederim. Bu nesne $ foo gerçekten ve yapamayacağı ne dışarıdan söylemek zor olduğunu beeing en belirgin nedeni.