Question

Je suis en train d'obtenir ce qui suit au travail, mais je suis perdu ...

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';
    }
}

Ce que je voudrais faire est de créer une instance de la classe SomethingElse au sein de la classe Foo. Cela fonctionne à l'aide =&. Mais quand j'étendre la classe Foo Bar avec classe, je pensais que l'enfant hérite de tous les attributs de données et méthodes de la classe parente. Cependant, il semble que $this->somethingelse ne fonctionne pas en classe enfant 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

Alors, est-il pas possible d'hériter de telle sorte? Et dois-je créer une nouvelle instance de SomethingElse de classe à l'intérieur Bar de classe si je veux l'utiliser là-bas? Ou suis-je manque quelque chose?

Merci d'avance pour votre aide.

Était-ce utile?

La solution

  

Je pensais que l'enfant hérite de tous les attributs de données et méthodes de la classe parente.

Il est vrai - la classe enfant hérite des variables statiques et des méthodes statiques de la classe parente. De plus, tous les objets enfants héritent des variables et des méthodes statiques et d'instance.

Une possibilité d'obtenir ce que vous voulez avec votre structure de classe existante est la suivante:

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

Une autre façon d'accomplir héritant d'une variable (dans ce cas, un objet) dans les cas d'enfants serait comme ceci:

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
    }
 }

Pour une très bonne vue d'ensemble des classes et des objets en PHP 5, un coup d'oeil ici: http://php.net/manual/en/language.oop5.php Assurez-vous de lire tout cela, peut-être une ou deux fois si OO est nouvelle pour vous.

Autres conseils

bar a une variable membre nommée somethingelse, qui est héritée de foo.

vous mixez objet et la portée de classe.

si vous voulez vraiment obtenir l'effet décrit, vous devez rendre votre variable statique, de sorte que son contexte est basé classe

Tout d'abord, il faut distinguer entre les variables statiques et d'instance. Les variables statiques sont partagées entre toutes les instances d'une classe, les variables d'instance ne sont pas.

Si vous voulez que chaque instance de Foo et Bar d'avoir exactement le même SomethingElse instance que vous avez à faire somethingelse $ statique:

statique somethingelse publique $

et vous devez changer la composition de la fonction Foo:

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

Pour accéder à ce champ statique, vous pouvez effectuer les opérations suivantes: $ Foo = new Foo (); // Je suis Foo foo- $> composition (); // Je suis une autre classe Foo: $ somethingelse-> test (); // Je suis une méthode dans la classe SomethingElse

$ bar = new Bar (); // Je suis Bar, ma mère est Foo Bar :: $ somethingelse-> test (); // Je suis une méthode dans la classe SomethingElse

Si vous voulez que chaque instance de Foo et Bar ont leur propre instance SomethingElse vous pouvez utiliser votre code, mais vous devez ajouter

$ bar-> composition ()

avant $ bar-> somethingelse-> test ();

En effet, avec

$ bar = new Bar ();

Vous avez créé une toute nouvelle instance de Bar et cette instance a une somethingelse $ la propriété, mais il n'a pas encore été fixée. Donc, vous devez appeler la composition () pour le régler.

Si tous les Foo et Bar doivent avoir le même SomethingElse instance exacte, vous devez utiliser à la place la version statique, car il réduit la mémoire nécessaire.

J'espère que cela peut vous aider. Sinon, je suis très heureux de vous expliquer davantage.

Dire que les classes partagent leurs attributs ne signifie pas que les objets partagent des valeurs d'attribut .

Comme d'autres l'ont noté, vous êtes des classes confusion avec les instances.

Note, vous obtiendrez la même erreur si vous avez fait:

$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

Pensez aux classes les moins abstraitement. Par exemple, vous pourriez avoir une classe, « personne », qui est une classe parente de « droits ».

Alors si vous avez fait:

me = new Personne $ ();    $ Moi-> prenom = "Thomas"

$ princeCharles = new droits ();

Vous ne voudriez pas $ princeCharles d'avoir l'un prenom attribut égal à « Thomas », et si vous souhaitez définir $ princeCharles-> prenom, vous ne pas modifier la valeur de l'attribut prenom de moi $ .

Les deux me $ et princeCharles $ ont un attribut 'PRENOM', mais nous ne partageons pas la valeur de cet attribut.

Je pense que votre problème sera résolu si dans le constructeur de la classe dérivée appellera le constructeur de la classe parent. Cela ne se produit pas garder par défaut en PHP il à l'esprit quand vous avez des problèmes avec les membres héritant de données.

Bar class Foo {étend     fonction publique __construct () {         parent :: __ construct ();

}

}

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top