2009-05-06 21 views
11

が、私はこのクラスを得た:PHPの子クラスへのアクセス親変数問題

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

私の問題は、次のとおりです。私はContactInformation上の$ idと$ユーザ名(および他の変数の多く)にアクセスしたいのですが、親::もしくはます$ this->は動作しませんが、私は毎回のように見えます。ユーザー名から現在の値にアクセスするために、任意のチャンス。新しいユーザー名 『「新しいContactInformationを....)PHPが作成されます』?

おかげ

+4

私はあなたが最初からクラスの拡張と抽象を読むために必要があると思います。 – OIS

+1

"private __construct" uff。 –

答えて

12

なぜUsernameのコンストラクタはprivateですか?Usernaを作成できないようにする場合は私は、Usernameクラスをabstractにします。また、親クラスから新しい連絡先情報を作成しないでください。

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

ユーザー名を直接インスタンス化するのではなく(今は不可能)、代わりにContactInformationを作成します。 ContactInformationは、独自のコンストラクターでUsernameコンストラクターを呼び出します。あなたはおそらく適切なサブクラスをしたい

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" 

+0

保護されたコンストラクタを宣言することは、シングルトンでは一般的です。しかし、あなたはおそらくこの場合は抽象的なを使用することになります。新しいUsername()を作成しようとすると、より有用なエラーが発生します。 –

+0

はい、シングルトンパターンでは一般的です。しかし、シングルトンクラスを拡張する必要があるとき、特にPHPではそうではない場合、シングルトンパターンは使いにくいです。多くの人々は、シングルトンパターンに欠陥があると主張し、単一のインスタンスをプログラム的に強制するのではなく、アプリケーション内に単一のインスタンスしか作成しないようにする方がよいと主張しています。 また、シングルトンパターンに従いたい場合、彼は "getInstance"メソッドと、__clone-magicメソッドをプライベートにする必要があります。 – PatrikAkerstrand

+0

ジェームズはシングルトンがここに当てはまると示唆しているとは思わない。彼はプライベートまたは保護されたコンストラクタが有効な用途を持っていることを指摘していました。 – Rob

8

親::方法は、あなたがあなたのサブクラスでオーバーライドしている親のメソッドにアクセスするために使用される、などの静的変数されています。基本クラスのコンストラクタにサブクラスを作成しないでください。あらゆる種類のOOPベストプラクティスを逆さまにして(疎結合など)、無限ループを作成します。 (新しいContactInformation()は、新しいContactInformation()を作成するUsernameコンストラクタを呼び出します。

あなたは、このような何かサブクラスをしたい場合:

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

をそれとも、デリゲートを使用することができますが、その後ContactInformation方法は、ユーザー名のプロパティに直接アクセスすることはないだろう。

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

私が正しくあなたを理解する場合は、そのオブジェクトに含まれるオブジェクトからオブジェクトのプロパティにアクセスしたいですか?これが正しければ、ここにそのを行う方法は次のとおりです。

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

あなたがしたのであれば:

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

あなたは、それは、あなたの例とは少し違う「test_value」

を取得したいです子クラスがアクセスできるように、親クラスのプロパティをパブリックにする必要があります。

これはすべてPHPで動作するため、明示的にクローンを作成しない限り、オブジェクトは常に参照渡しとなります。

+0

この場合、合成と継承の両方を使用しています。後者は不要です。あなたの事例を明確にすることはできますか? – Rob

2

最初にContactInformationを作成すると、非プライベートプロパティとメソッドのすべてがUsernameにも含まれます。別のUsernameインスタンスは必要ありません。

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

しかし、すべてのフィールドが保護されているので、これは仕事に行くされていません。

$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(); 
関連する問題