2009-05-06 17 views
11

मैं इस वर्ग है:पीएचपी बाल वर्ग एक्सेस जनक चर समस्या

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 पर उपयोग करना चाहते हैं, लेकिन माता-पिता :: या $ this-> काम नहीं करता, हर तरह लग रहा है मैं करता हूँ "नए ContactInformation ....) PHP एक बनाता है" नया नाम "। प्रयोक्ता नाम से वर्तमान मान तक पहुँचने के लिए किसी भी मौका?

धन्यवाद

+4

मैं तुम्हें कक्षा विस्तार और खरोंच से अमूर्त पढ़ने की जरूरत है लगता है। – OIS

+1

"निजी __construct" uff। –

उत्तर

12

क्यों यूजरनेम कन्स्ट्रक्टर निजी है? अगर आप यूज़र्न बनाने के लिए असंभव बनाना चाहते हैं मैं, उपयोगकर्ता नाम वर्ग अमूर्त बनाओ। साथ ही, अभिभावक वर्ग से नई संपर्क जानकारी न बनाएं। आप के बजाय एक ContactInformation बनाने के बजाय प्रयोक्ता नाम सीधे instantiating (जो अब असंभव है) की

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

अब,,: यहाँ एक और तरीका यह डाल करने के लिए है। संपर्क जानकारी तब उपयोगकर्ता नाम निर्माता को अपने स्वयं के कन्स्ट्रक्टर में कॉल करती है।

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

सिंगलटन में संरक्षित कन्स्ट्रक्टर घोषित करना आम है। लेकिन आप शायद इस मामले में सार का उपयोग करने के बारे में सही हैं, इसलिए यदि आप एक नया उपयोगकर्ता नाम() बनाने की कोशिश करते हैं तो आपको और अधिक उपयोगी त्रुटियां मिलेंगी; –

+0

हां, यह सच है कि यह सिंगलटन-पैटर्न में आम है। लेकिन सिंगलटन-पैटर्न का उपयोग करना बहुत अच्छा नहीं है जब आपको सिंगलटन-क्लास को विस्तारित करने की आवश्यकता होती है, खासकर PHP में नहीं। बहुत से लोग तर्क देते हैं कि सिंगलटन-पैटर्न त्रुटिपूर्ण है, और यह सुनिश्चित करना बेहतर है कि, एक उदाहरण को प्रोग्रामेटिक रूप से मजबूर करने के बजाय, एप्लिकेशन में केवल एक ही उदाहरण बनाया गया है। इसके अलावा, अगर वह सिंगलटन-पैटर्न का पालन करना चाहता है तो उसे "getInstance" -method की आवश्यकता होगी और __clone-magic विधि को निजी बनाना होगा। – PatrikAkerstrand

+0

मुझे नहीं लगता कि जेम्स सुझाव दे रहे थे कि सिंगलटन यहां लागू है; वह इंगित कर रहे थे कि एक निजी या संरक्षित निर्माता के पास वैध उपयोग हैं। – Rob

8

माता पिता :: विधि केवल माता-पिता के तरीकों है कि आप अपने उपवर्ग में अधिरोहित किया है, या जैसे स्थैतिक चर का उपयोग किया जाता है। बेस क्लास के कन्स्ट्रक्टर में सबक्लास नहीं बनाएं, जो ओओपी सर्वोत्तम प्रथाओं को उल्टा (ढीला युग्मन, इत्यादि) के सभी प्रकारों को एक अनंत लूप बनाते समय बदल देता है। (नया ContactInformation() उपयोगकर्ता नाम कन्स्ट्रक्टर को कॉल करता है जो एक नया ContactInformation() बनाता है जो ...)।

आप एक उपवर्ग, कुछ इस तरह करना चाहते हैं:

/** 
* 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(); 
संबंधित मुद्दे