2012-11-27 29 views
10

मैं एक वर्ग में कई बार एक कार्यक्षमता का पुन: उपयोग करना चाहता हूं। इस कार्यशीलता के लिए एक निजी चर पर निर्भर करता है:एक विशेषता के लिए एक परिवर्तनीय निजी बनाने के लिए कैसे?

class User { 
    use Address { 
     getAddress as getHomeAddress; 
     setAddress as setHomeAddress; 

     getAddress as getWorkAddress;    
     setAddress as setWorkAddress; 
    } 
} 

समस्या है, ऐसा करके, निजी चर $address साझा किया जाता है:

trait Address { 
    private $address; 

    public function getAddress() { 
     return $this->address; 
    } 

    public function setAddress($address) { 
     $this->address = $address; 
    } 
} 

एक ही रास्ता मैं use the trait twice पाया है, तो निम्न है विभिन्न तरीकों, और कोड भर में अपेक्षा के अनुरूप काम नहीं करेगा:

$user = new User(); 
$user->setHomeAddress('21 Jump Street'); 
echo $user->getWorkAddress(); // 21 Jump Street 

वहाँ एक समाधान वास्तव में विशेषता का उपयोग करने के दो बार है, जबकि इसकी जनसंपर्क साझा नहीं ivate चर?

उत्तर

15

use के साथ एक विशेषता घोषित करने से उस विशेषता का एक उदाहरण नहीं बन जाएगा। लक्षण मूल रूप से केवल कोड होते हैं जो प्रतिलिपि वर्ग में कॉपी और चिपकाए जाते हैं। as केवल उस विधि के लिए उपनाम बनाएगा, उदा। यह

public function getHomeAddress() 
{ 
    return $this->getAddress(); 
} 

जैसी कुछ उपयोगकर्ता श्रेणी में कुछ जोड़ देगा। लेकिन यह अभी भी केवल एक विशेषता होगी। दो अलग-अलग $address गुण नहीं होंगे, लेकिन केवल एक ही।

आप विधियों को निजी बना सकते हैं और फिर विधि नाम पर स्विच/आवरण करके और पते के लिए सरणी का उपयोग करके __call के माध्यम से किसी भी सार्वजनिक कॉल का प्रतिनिधि बना सकते हैं।

trait Address { 
    private $address = array(); 

    private function getAddress($type) { 
     return $this->address[$type]; 
    } 

    private function setAddress($type, $address) { 
     $this->address[$type] = $address; 
    } 

    public function __call($method, $args) { 
     switch ($method) { 
      case 'setHomeAddress': 
       return $this->setAddress('home', $args[0]); 
      // more cases … 
     } 
    } 
} 

लेकिन यह केवल कीड़े का एक कर है।

दूसरे शब्दों में, आप उन चीज़ों को संवेदना से नहीं कर सकते जो आप गुणों के साथ करने की कोशिश कर रहे हैं। या तो दो अलग-अलग लक्षणों का उपयोग करें। या अच्छे पुराने एकत्रीकरण का उपयोग करें और ठोस प्रॉक्सी विधियों को जोड़ें।

+3

हालांकि मैं समझता हूँ कि लक्षण * instantiated नहीं कर रहे हैं *, मैं अभी भी अपने निजी चर उम्मीद कर रहा था उन्हें प्रयोग है, इस प्रकार संभावित उन्हें एक ही कक्षा में कई बार उपयोग करने की अनुमति वर्ग को दिखाई नहीं हो सकता है, aliased विधि के साथ नाम। ऐसा लगता है कि मैं गलत था, इसलिए आपके उत्तर के लिए धन्यवाद! – Benjamin

+0

@ उस विशेषता का उपयोग करते हुए प्रत्येक वर्ग में बेंजामिन का '$ पता' चर का अपना उदाहरण होगा, लेकिन यह स्पष्ट रूप से कक्षा का उपयोग करके कक्षा के लिए दृश्यमान होगा, क्योंकि लक्षण केवल कक्षाओं में कुछ व्यवहार जोड़ते हैं। –

+0

@ मैटेटे हाँ, यह मेरे सिर में थोड़ा स्पष्ट हो रहा है ... यह एकाधिक विरासत से अलग है, क्योंकि विरासत के साथ चर केवल सुपरक्लास में दिखाई देगा, जहां यहां विशेषता से निजी चर केवल "प्रतिलिपि" है वास्तविक वर्ग – Benjamin

0

मैंने पुष्टि की है कि आप एक ही समारोह को कई बार उपनाम कर सकते हैं, जो मुझे आश्चर्यचकित था। यद्यपि ज़ेंडस्टूडियो फ़ंक्शन के अंतिम उपनामों पर केवल 'कोड सहायता' प्रतीत होता है।

एक ही फ़ंक्शन को उपनाम करने में सक्षम होने के कारण कई बार खुद को कुछ रोचक व्यवहार में उधार दे सकता है यदि ट्राइट फ़ंक्शन निर्धारित कर सकता है कि इसे किस नाम के रूप में जाना जाता था। लेकिन ऐसा नहीं लगता है कि हम एक विशेषता समारोह के भीतर 'एलियाड' फ़ंक्शन निर्धारित कर सकते हैं।

यहाँ अपने परीक्षण कोड है:

<?php 
trait TestTrait 
{ 
    public function test() { print __CLASS__ . ', ' . __TRAIT__ . ', ' . __METHOD__ . ', ' . __FUNCTION__ . "\n"; } 
} 
class TestClass 
{ 
    use TestTrait { test as test1; test as test2; } 
} 
$c = new TestClass(); 
$c->test1(); 
$c->test2(); 

आउटपुट:

TestClass, TestTrait, TestTrait::test, test 
TestClass, TestTrait, TestTrait::test, test 

शायद यह एक नया ALIAS विशेषता कार्यों को निर्धारित करने के क्या उर्फ ​​वे के रूप में कहा जाता था के लिए निरंतर जोड़ने के लिए अच्छा होगा।

वास्तव में मैं इस के लिए पीएचपी सुविधा का अनुरोध बनाया है:

https://bugs.php.net/bug.php?id=63629

0

मैं पार्टी के लिए देर से एक छोटे से हो सकता है लेकिन व्यवहार आप को बनाने का प्रयास कर रहे हैं कुछ है कि द्वारा कवर किया जाना चाहिए नहीं है एक विशेषता, लेकिन सरल वस्तु संरचना द्वारा।

<?php 
class Adddress { 
    private $street; 
    private $number; 
    public function __construct(string $street, ?string $number) {} 
    public function street() : string {} 
    public function number() : string {} 
} 
class User { 
    private $homeAddress; 
    private $workAddress; 
    public function getHomeAddress() : Address {} 
    public function setHomeAddress(Address $homeAddress) : self {} 
    public function getWorkAddress() : Address {} 
    public function setWorkAddress(Address $workAddress) : self {} 
}