2009-05-06 15 views
11

ich diese Klasse bekam:PHP Kinder Klasse zugreifenden Eltern Variable Problem

Class Username { 
protected $id; 
protected $username; 
protected $contact_information; 

    private __construct($id) { 
     $this->id = (int) $id; // Forces it to be a string 
     $contact_information = new ContactInformation($this->id); 
    } 
} 

Class ContactInformation extends Username { 
    protected $mobile; 
    protected $email; 
    protected $nextel_id; 
    ..... 
} 

Mein Problem ist: Ich habe die $ id und $ username (und viele andere Variablen) zugreifen möchten, auf Contact, aber parent :: oder $ this-> nicht funktioniert, sieht aus wie jedes Mal wenn ich tue „neue Contact ....) PHP eine schafft‚neuen Benutzername‘. Jede Chance, die aktuellen Werte von Benutzername zugreifen?

Dank

+4

Ich glaube, Sie brauchen Klassenerweiterung und Abstraktion von Grund auf neu zu lesen. – OIS

+1

"private __construct" uff. –

Antwort

12

Warum Ist der Username-Konstruktor privat? Wenn du damit verhindern willst, dass ein Userna erstellt wird Ich mache die Username-Klasse abstrakt. Machen Sie auch keine neuen Kontaktinformationen von der übergeordneten Klasse. Hier ist eine andere Weise zu setzen:

abstract class Username { 
    protected $id; 
    protected $username; 

    public __construct($id) { 
     $this->id = (int) $id; // Forces it to be a string 
    } 
} 

class ContactInformation extends Username { 
    protected $mobile; 
    protected $email; 
    protected $nextel_id; 
    public __construct($id, $mobile, $email, $nextel_id) { 
     parent::__construct($id) 
     $this->mobile = $mobile; 
     .... 
    } 
} 

Statt nun Instanziieren den Benutzernamen direkt (was jetzt nicht möglich ist), können Sie stattdessen eine Contact erstellen. ContactInformation ruft dann den Username-Konstruktor in einem eigenen Konstruktor auf.

+0

Das Deklarieren eines geschützten Konstruktors ist in Singletons üblich. Aber Sie haben wahrscheinlich recht, wenn Sie in diesem Fall abstract verwenden, sodass Sie mehr nützliche Fehler erhalten, wenn Sie versuchen, einen neuen Benutzernamen zu erstellen(); –

+0

Ja, es stimmt, dass es im Singleton-Muster üblich ist. Aber das Singleton-Muster ist nicht großartig, wenn Sie die Singleton-Klasse erweitern müssen, besonders nicht in PHP. Viele Leute argumentieren auch, dass das Singleton-Muster fehlerhaft ist und dass es besser ist sicherzustellen, dass, anstatt eine einzelne Instanz programmgesteuert zu erzwingen, nur eine einzige Instanz in der Anwendung erzeugt wird. Auch wenn er dem Singleton-Muster folgen möchte, benötigt er eine "getInstance" -Methode und auch um die __clone-magic Methode privat zu machen. – PatrikAkerstrand

+0

Ich glaube nicht, dass James vorgeschlagen hat, dass Singleton hier anwendbar ist; Er wies darauf hin, dass ein privater oder geschützter Konstruktor eine gültige Verwendung hat. – Rob

8

Die parent :: Methode wird nur für den Zugriff auf übergeordnete Methoden verwendet, die Sie in Ihrer Unterklasse außer Kraft gesetzt haben, oder statische Variablen wie:

class Base 
{ 
    protected static $me; 

    public function __construct() 
    { 
     self::$me = 'the base'; 
    } 

    public function who() { 
     echo self::$me; 
    } 
} 

class Child extends Base 
{ 
    protected static $me; 

    public function __construct() 
    { 
     parent::__construct(); 
     self::$me = 'the child extends '.parent::$me; 
    } 

    // until PHP 5.3, will need to redeclare this 
    public function who() { 
     echo self::$me; 
    } 
} 

$objA = new Base; 
$objA->who(); // "the base" 

$objB = new Child; 
$objB->who(); // "the child extends the base" 

Sie wahrscheinlich eine richtige Unterklasse will. Erstellen Sie im Konstruktor der Basisklasse keine Unterklasse, die alle Arten von OOP-Best Practices auf den Kopf stellt (lose Kopplung usw.) und gleichzeitig eine Endlosschleife erstellt. (new ContactInformation() ruft den Username-Konstruktor auf, der eine neue ContactInformation() erstellt, die ...).

Wenn Sie eine Unterklasse, etwa wie folgt:

/** 
* Stores basic user information 
*/ 
class User 
{ 
    protected $id; 
    protected $username; 

    // You could make this protected if you only wanted 
    // the subclasses to be instantiated 
    public function __construct ($id) 
    { 
     $this->id = (int)$id; // cast to INT, not string 

     // probably find the username, right? 
    } 
} 

/** 
* Access to a user's contact information 
*/ 
class ContactInformation extends User 
{ 
    protected $mobile; 
    protected $email; 
    protected $nextel; 

    // We're overriding the constructor... 
    public function __construct ($id) 
    { 
     // ... so we need to call the parent's 
     // constructor. 
     parent::__construct($id); 

     // fetch the additional contact information 
    } 
} 

Oder Sie könnten einen Delegaten verwenden, aber dann würden die Contact Methoden haben keinen direkten Zugriff auf den Benutzername Eigenschaften.

class Username 
{ 
    protected $id; 
    protected $contact_information; 

    public function __construct($id) 
    { 
     $this->id = (int)$id; 
     $this->contact_information = new ContactInformation($this->id); 
    } 
} 

class ContactInformation // no inheritance here! 
{ 
    protected $user_id; 
    protected $mobile; 

    public function __construct($id) 
    { 
     $this->user_id = (int)$id; 
     // and so on 
    } 
} 
1

Wenn ich Sie richtig verstehe, möchten Sie auf Eigenschaften eines Objekts von einem Objekt zugreifen, das in diesem Objekt enthalten ist? Wenn dies richtig ist, hier ist, wie ihre getan:

class A { 

    // These are the properties you want to access from the child object 
    public $property_a; 
    public $property_b; 
    public $property_c; 

    // This is the child object variable 
    public $child_object; 

    public function __construct() { 

    // Pass 'this' into the child so that the child has a reference back to the parent 
    $this->child_object = new B($this); 
    } 
} 

class B { 

    // Holds a reference to the parent object 
    protected $parent_object; 

    public function __construct($object) { 

    // Remember the reference to the parent object 
    $this->parent_object = $object; 
    } 

    // Just a Demonstration Method 
    public print_parent_property_a() 
    { 
    // Reach into the referred parent object, and get it's property 
    print $this->parent_object->property_a; 
    } 
} 

Also, wenn Sie tun sollten:

$my_object = new A(); 
$my_object->property_a = 'test_value'; 
$my_object->child_object->print_parent_property_a(); 

Sie ‚test_value‘ bekommen

Es ist leicht von Ihrem Beispiel in dass die Elternklasseneigenschaften öffentlich sein müssen, damit das Kind darauf zugreifen kann.

Das funktioniert alles, weil in PHP Objekte immer als Referenz übergeben werden, es sei denn, Sie klonen sie explizit.

+0

Sie haben in diesem Fall sowohl Komposition als auch Vererbung verwendet. Letzteres ist unnötig. Können Sie Ihr Beispiel verdeutlichen? – Rob

2

Zuerst, wenn Sie eine ContactInformation erstellen, enthält es auch alle nicht privaten Eigenschaften und Methoden von Username. Sie benötigen keine separate Username Instanz.

Class Username { 
    protected $id; 
    protected $username; 

    protected __construct($id) { 
     $this->id = (int) $id; // Forces it to be a string 
    } 
} 

Class ContactInformation extends Username { 
    protected $mobile; 
    protected $email; 
    protected $nextel_id; 
    // Pretend that these are here because they're defined in my parent 
    //protected $id; 
    //protected $username; 

    public __construct($id) { 
     parent::__construct($id); 
     echo $this->id; //Should echo 1 
    } 
} 

Da jedoch alle Felder geschützt sind, wird dies nicht funktionieren:

$contact_information = new ContactInformation(1); // Works fine 
echo $contact_information->id; 
// Whoops, visibility error because id isn't public 
0
<?php 

abstract class employee 
{ 
    //create member variable in parent class 

    protected $name; 
    protected $id; 
    protected $mobile; 

    //constructor of parent class 
    public function __construct($n , $i , $m) 
    { 
     $this->name=$n; 
     $this->id=$i; 
     $this->mobile=$m; 
    } 
    //create method will return name 
    public function ShowFullName() 
    { 

     return $this->name; 
    } 
//create method will return contact 
    public function ShowContact() 
    { 

     return $this->mobile; 
    } 

} 

class FulltimeEmployee extends employee 
{ 

    private $days; 
    private $salary; 



     //create child constructor 
    public function __construct($n , $i , $mo , $d , $s) 
    { 
     $this->days=$d; 
     $this->salary=$s; 

     //calling parent constructor now we can use parent class member while calling child class constructor 
     parent::__construct($n , $i , $mo); 
    } 

    public function calculate() 
    { 

     return $this->salary * $this->days; 

    } 
} 

//providing data to child class constructor including parent class values 
$child = new FulltimeEmployee("james",120,9033474118 , 2 , 200); 
echo $child->calculate(); 
echo $child->ShowFullName();