Domanda

Sto cercando di ottenere la seguente al lavoro, ma io sono in perdita ...

class Foo {
    public $somethingelse;

    function __construct() {
        echo 'I am Foo';
    }
    function composition() {
        $this->somethingelse =& new SomethingElse();
    }
}
class Bar extends Foo {
    function __construct() {
        echo 'I am Bar, my parent is Foo';
    }
}
class SomethingElse {
    function __construct() {
        echo 'I am some other class';
    }
    function test() {
        echo 'I am a method in the SomethingElse class';
    }
}

Quello che mi piacerebbe fare è creare un'istanza della classe SomethingElse all'interno della classe Foo. Questo funziona utilizzando =&. Ma quando mi estendo classe Foo con classe da bar, ho pensato che il figlio eredita tutti gli attributi di dati e metodi dalla classe genitore. Tuttavia, sembra che $this->somethingelse non funziona in classe bambini Bar:

$foo = new Foo(); // I am Foo
$foo->composition(); // I am some other class
$foo->somethingelse->test(); // I am a method in the SomethingElse class

$bar = new Bar(); // I am Bar, my parent is Foo
$bar->somethingelse->test(); // Fatal error: Call to a member function test() on a non-object

Quindi, non è possibile ereditare in modo tale? E dovrei creare una nuova istanza della classe SomethingElse dall'interno classe Bar se voglio usarlo lì? O mi sto perdendo qualcosa?

Grazie in anticipo per il vostro aiuto.

È stato utile?

Soluzione

  

Ho pensato che il figlio eredita tutti gli attributi dei dati e dei metodi della classe genitore.

Questo è vero - la classe figlio eredita le variabili statiche e metodi statici della classe padre. Inoltre, tutti gli oggetti figlio erediteranno le variabili ei metodi statici e di istanza.

Una possibilità per ottenere ciò che si vuole con la vostra struttura di classe esistente è questo:

$bar = new Bar();
$bar->composition();// here you are calling the parent method, sets instance var $somethineelse
$bar->somethingelse->test();// now you can call methods

Un altro modo per realizzare ereditare una variabile (in questo caso un oggetto) in casi bambino sarebbe in questo modo:

class Foo {
    protected $somethingelse;
    public function __construct() {
        $this->somethingelse = new SomethingElse();
    }
}

class Bar extends Foo {
    public function __construct() {
        parent::__construct();
        // now i've got $somethingelse
    }
 }

Per una buona panoramica di classi e oggetti in PHP 5, un'occhiata qui: http://php.net/manual/en/language.oop5.php Assicurarsi di leggere tutto, forse un paio di volte se OO è una novità per voi.

Altri suggerimenti

bar ha una variabile membro denominata somethingelse, che viene ereditato da foo.

si stia mescolando ambito oggetto e classe.

se si vuole davvero raggiungere l'effetto descritto, è necessario rendere la vostra variabile statica, quindi il suo contesto si basa classe

In primo luogo, si deve distinguere tra variabili statiche e di istanza. Le variabili statiche sono condivise tra tutte le istanze di una classe, le variabili di istanza non sono.

Se si desidera che ogni istanza di Foo e Bar per avere la stessa identica SomethingElse-Instance devi fare $ somethingelse statica:

static $ somethingelse pubblico

e si dovrebbe cambiare la composizione-funzione Foo:

function composition() {
    self::$somethingelse = new SomethingElse();
}

Per accedere a questo campo statico è possibile effettuare le seguenti operazioni: $ Foo = new Foo (); // Sono Foo $ Foo-> composizione (); // Sono qualche altra classe Foo: $ somethingelse-> test (); // Io sono un metodo nella classe SomethingElse

$ bar = new Bar (); // Sono Bar, il mio genitore è Foo Bar :: $ somethingelse-> test (); // Io sono un metodo nella classe SomethingElse

Se si desidera che ogni istanza di Foo e Bar hanno la loro propria istanza SomethingElse è possibile utilizzare il codice, ma è necessario aggiungere

$ bar-> composizione ()

prima di $ bar-> somethingelse-> test ();

Questo perché con

$ bar = new Bar ();

si creata una nuova istanza di Bar e tale istanza ha una proprietà $ somethingelse, ma non è ancora stata fissata. Quindi è necessario chiamare composizione () per impostarlo.

Se ogni Foo e bar dovrebbero avere la stessa identica SomethingElse-esempio, si dovrebbe utilizzare la versione statica, invece, perché riduce la memoria necessaria.

Spero che questo ti può aiutare. In caso contrario, io sono molto felice di spiegare ulteriormente.

Dire che le classi attributi di condivisione non significa che gli oggetti condividano valori di attributo .

Come altri hanno notato, sei classi confuse con le istanze.

Nota, si otterrebbe lo stesso errore, se avete fatto:

$foo = new Foo(); // I am Foo
$foo->composition(); // I am some other class
$foo->somethingelse->test(); // I am a method in the SomethingElse class

$foo2 = new Foo(); // I another Foo
$foo2->somethingelse->test(); // Fatal error: Call to a member function test() on a non-object

Si pensi alle classi meno astrattamente. Ad esempio, si potrebbe avere una classe, "Persona", che è una classe genitore di "royalty".

Quindi, se avete fatto:

$ me = new Person ();    $ Me-> firstName = "Thomas"

$ princeCharles = new Royalty ();

Non si vorrebbe $ princeCharles avere l'un firstName attributo uguale a "Thomas", e se si desidera impostare $ princeCharles-> firstName, non è che per cambiare il valore dell'attributo firstName di $ me .

Sia io $ e $ princeCharles hanno un attributo 'Nome', ma noi non condividono la Valore di tale attributo.

Credo che il problema sarà risolto se nel costruttore della classe derivata chiamerà il costruttore della classe genitore. Ciò non si verifica per impostazione predefinita in PHP in modo da tenere a mente quando si hanno problemi con eredita membri di dati.

classe Bar estende Foo {     Funzione pubblica __construct () {         parent :: __ construct ();

}

}

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top