Classi PHP5: ereditare una classe composta?
-
13-09-2019 - |
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.
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 ();
}
}