2009-08-11 6 views
5

PHP ऑब्जेक्ट ओवरलोडिंग को here समझाया गया है।PHP में ऑब्जेक्ट ओवरलोडिंग द्वारा क्या लाभ प्रदान किया जाता है?

असल में यह आपको कुछ कस्टम कार्रवाइयों को परिभाषित करने की अनुमति देता है जब एक पहुंच योग्य वस्तु संपत्ति या विधि का उपयोग किया जाता है।

इस सुविधा के लिए कुछ व्यावहारिक उपयोग क्या हैं?

उत्तर

4

आमतौर पर, जब आप किसी तृतीय पक्ष API के साथ संचार कर रहे होते हैं या जब विधि/सदस्य संरचना अस्पष्ट होती है तो वे विधियां उपयोगी होती हैं।

मान लें कि आप एक सामान्य XML-RPC wrapper लिख रहे हैं। चूंकि आप डब्लूडीएल फ़ाइल डाउनलोड करने से पहले आपके लिए उपलब्ध विधियों को नहीं जानते हैं, इसलिए ओवरलोडिंग का उपयोग करना समझ में आता है।

तब, निम्न लेखन के बजाय:

$xmlrpc->call_method('DoSomething', array($arg1, $arg2)); 

आप उपयोग कर सकते हैं:

$xmlrpc->DoSomething($arg1, $arg2); 

जो एक और अधिक प्राकृतिक वाक्य रचना है।


आप सदस्य ओवरलोडिंग का उपयोग वैरिएबल ऑब्जेक्ट्स के लिए विधि अधिभार के रूप में भी कर सकते हैं।

केवल एक चीज जिसके लिए आप देखना चाहते हैं: इसके उपयोग को केवल चर-संरचना वस्तुओं के लिए सीमित करें या केवल गेटर्स और सेटर्स के लिए सिंटैक्टिकल शॉर्टकट के लिए इसका उपयोग करें। यह भावना अपनी कक्षा एक से अधिक तरीकों में व्यापार तर्क अलग करने में getters और setters रखने के लिए करता है, लेकिन एक शॉर्टकट के रूप में उपयोग में कोई बुराई नहीं है:

class ShortcutDemo { 
    function &__get($name) { 
    // Usually you want to make sure the method 
    // exists using method_exists, but for sake 
    // of simplicity of this demo, I will omit 
    // that logic. 
    return call_user_method('get'.$name, $this); 
    } 

    function __set($name, &$value) { 
    return call_user_method('set'.$name, $this, $value); 
    } 

    private $_Name; 

    function &getName() { return $this->_Name; } 
    function setName(&$value) { $this->_Name = $value; } 
} 

इस तरह आप को मान्य करने के अपने getters और setters उपयोग जारी रख सकते और अपने डेटा सेट, और अभी भी इस तरह के रूप वाक्यात्मक शॉर्टकट का उपयोग:

$shortcut->Name = 'Hello'; 
0

एक अन्य विधि कि एंड्रयू का उल्लेख नहीं था (या लेखन के समय का उल्लेख नहीं किया गया है) getters और setters से छुटकारा पाने के लिए है। इस प्रकार की प्रत्येक सेटर और गेटर घोषित करने के लिए होने की:

$obj->setName("Chacha"); 
$obj->setRep(10000000000000000000000); 

आप के बजाय सिर्फ कर सकते हैं

$obj->Name = "chacha"; 
$obj->Rep = 100000000000000000; 

दूसरी विधि और अधिक प्राकृतिक है।

जादू के तरीके मूल रूप से ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग के विचार को आगे बढ़ाते हैं, और यह विचार कि आप नौकरी को कैसे कार्यान्वित करते हैं, बाहरी दुनिया से कोई फर्क नहीं पड़ता। जादू के तरीकों के माध्यम से, यह आपको अपने वैरिएबल को स्टोर करने की इजाजत देता है, हालांकि आप चाहते हैं कि अन्य वर्गों को उन्हें प्राकृतिक तरीके से सेट करें।

उदाहरण: मैं अपने सभी उपयोगकर्ता की खाता वरीयताओं को एक ही सरणी में स्टोर कर सकता हूं जो इसे सत्र तक सभी को धक्का देने के लिए वास्तव में आसान बनाना होगा।

यदि मैंने इसके लिए मैजिक विधि का उपयोग नहीं किया है, तो मुझे या तो सेट का एक गुच्छा बनाना होगा, जिसका अर्थ है अधिक कोड लिखना, या सरणी तक सीधी पहुंच की अनुमति देना, जो कार्यान्वयन का खुलासा करता है, इसलिए मैं जाकर इसे बाद में नहीं बदल सकता है।

इसके बजाए, मैजिक मेथड का उपयोग करके, मैंने उन्हें नियमित रूप से चर सेट किया है, और मैं इसे आंतरिक रूप से सौदा करता हूं।

+0

हालांकि मैं अभी तक गेटर्स और सेटर्स से छुटकारा नहीं पाउंगा। विभिन्न व्यक्तिगत गुणों के लिए व्यवसाय नियम युक्त कई विधियां आमतौर पर बनाए रखने और डीबग करना आसान होती हैं, फिर एक विशाल विधि जिसमें सभी गुणों के लिए सभी व्यावसायिक नियम होते हैं। मैं 'getX', 'setX' को कॉल करने के शॉर्टकट तरीके के लिए' __get()' और '__set()' का उपयोग करूंगा। ऑब्जेक्ट अधिभार उपयोग केवल परिवर्तनीय संरचना वस्तुओं के लिए रखा जाना चाहिए। –

+0

मेरा अद्यतन संस्करण पढ़ें। –

+0

हालांकि, यह वास्तव में सी # प्राप्त/सेट संपत्ति की तरह काम नहीं करता है। कम से कम लचीला नहीं, अगर आप सेट किए जा रहे हैं या सत्यापित करना चाहते हैं। – Extrakun

0

आप इसे उन मामलों के लिए उपयोग कर सकते हैं जब कक्षा में जारी करने और सेट करने के लिए जटिल नियम होते हैं। उदाहरण के लिए, एक वैरिएबल $ ए युक्त एक वर्ग ऑब्जेक्ट्स या अन्य संसाधनों की एक सरणी हो सकती है, और जब सेट नहीं होती है, तो उन्हें कुछ अन्य कार्यक्षमताओं को निष्पादित करना होता है।

हालांकि मुझे यकीन नहीं है कि वे एक नई संपत्ति जोड़ने और गैर-निजी संपत्ति को पुनर्प्राप्त करने की अनुमति क्यों देते हैं, लेकिन आप इसे किसी अन्य वस्तु को कॉल करके किसी ऑब्जेक्ट की आंतरिक स्थिति को बदलने के लिए उपयोग कर सकते हैं संपत्ति/सदस्य चर सेट किया जा रहा है।

कुछ मामलों में, इस ऑपरेटर सी ++

0

संदेश में अधिक भार है जब आप बना या एकत्रित किया है वस्तुओं के लिए अग्रेषण जहां बहुरूपता एक विकल्प नहीं है (जैसे कि, क्या आप नियंत्रित नहीं कर सकते एक पुस्तकालय वर्ग का उपयोग कर रहे जैसा दिखता है)।

<?php 

// Class A is final, so we can't make subclasses. 
final class A 
{ 
    public function hello($callback) 
    { 
    echo call_user_func($callback, 'hello world'); 
    } 
} 

// so instead, we make a wrapper class that will take an instance 
// of A as an aggregate 
class B 
{ 
    private $a; 

    public function __construct(A $a) 
    { 
    $this->a = $a; 
    } 

    // this mimics inheritance on the aggregate object 
    // method calls are automatically forwarded to instance of A 
    // if they are valid 
    public function __call($method, $args) 
    { 
    if (method_exists($this->a, $method)) 
    { 
     return call_user_func_array(array($this->a, $method), $args); 
    } 
    throw new Exception("Method [$method] not found."); 
    } 
} 

class C extends B 
{ 
    // This mimics overriding an "inherited" method 
    public function hello($callback) 
    { 
    echo call_user_func($callback, 'bonjour le monde'); 
    } 
} 

$a = new A; 

$b = new B($a); 
$c = new C($a); 

$b->hello('strtoupper'); 
$c->hello('strtoupper'); 
0

यह सुविधा वास्तव में what object oriented programming is all about है, इसके आविष्कारक एलन Kay के मन में: वस्तुओं एक दूसरे को संदेश भेजने, और संभवतः संदेश के किसी भी प्रकार के लिए प्रतिक्रिया। संकलन समय पर तय किए गए तरीके इस अवधारणा के सीमित (लेकिन अधिक कुशल) कार्यान्वयन हैं। यही वह जगह है जहां के के प्रसिद्ध उद्धरण "मैंने ऑब्जेक्ट उन्मुख शब्द का आविष्कार किया, और मैं आपको बता सकता हूं कि सी ++ मेरे मन में नहीं था।" से आता है।

मूल रूप से, ऑब्जेक्ट अभिविन्यास की इस मूल, व्यापक परिभाषा को लागू करने के लिए संकलित समय पर निर्धारित एक विधि के बिना ऑब्जेक्ट्स को विधि कॉल पर प्रतिक्रिया करने की अनुमति देता है। अधिकांश आधुनिक "गतिशील" भाषाएं इसे एक रूप में या किसी अन्य रूप में समर्थन देती हैं।

इसके लिए क्या अच्छा है: अच्छे उदाहरण के लिए Groovy's Builders पर एक नज़र डालें। असल में, यह डेटा नामों को डेटा में बदलकर बहुत कॉम्पैक्ट कम-रिडंडेंसी सिंटैक्स की अनुमति देता है।

0

एक तरीका, जो काफी प्रशंसक है, मैंने इसका उपयोग ऑब्जेक्ट रिलेशनल मैनेजमेंट (ओआरएम) सिस्टम जैसे लिंक बनाने के लिए किया है। फिर आप डेटाबेस तालिका संरचना को लोड कर सकते हैं और डेटा (डेटाबेस तालिका से) में हेरफेर कर सकते हैं जैसे कि यह केवल एक वस्तु थी।

अर्थात

include('blibrary/bLinq.class.inc'); 

$linq = new bLinq(new bLinqSql('mysql://dsn')); 
$r = $linq->from('Users') 
      ->password 
      ->select(); 

जो निम्नलिखित एसक्यूएल करने के लिए अनुवाद:

SELECT `password` from Users; 

password चयन बयान में अतिभारित विधि से आता है।

परिणाम की तरह इस्तेमाल किया जा सकता है:

(array)$r->password; // which outputs an array multiple results of password; 
(string)$r->password; // which outputs a string of the first password hash; 
$r->password[2];  // which outputs a string of the third password hash; 

मुद्दा यह है कि शब्द "password" किसी भी अन्य क्षेत्र के लिए उड़ान भरने पर डेटाबेस में जब प्रोग्रामिंग प्रतिस्थापित किया जा सकता है।

0

मैं वस्तुओं को एक साथ जोड़ने के लिए __get और __set का उपयोग करता हूं उदा।

$user = new User(); 
echo $user->Profile->views; 

यह (आमतौर पर) कुछ जोड़ने users.id = profile.user_id एसक्यूएल कहता है।

0

गुण (जैसे कि पायथन या सी # में)।- $instance->bar

<?php 
class Foo extends Object 
{ 
    public $bar; 
} 

आप इस प्रॉपर्टी को प्राकृतिक तरीके से उपयोग कर सकते हैं: उदाहरण के लिए जब आप इस in Nette की तरह कुछ का उपयोग के लिए, आप कुछ वर्ग है, जो सार्वजनिक रूप में कुछ संपत्ति से पता चलता पैदा करते हैं। लेकिन जब आप कुछ मान्यकरण करना आदि चाहते हैं, तो आप सिर्फ गेटर और सेटर जोड़ें:

<?php 
class Foo extends Object 
{ 
    private $bar; 

    public function getBar() 
    { 
     return $this->bar; 
    } 

    public function setBar($bar) 
    { 
     if ($bar === NULL) throw new Exception('…'); 
     $this->bar = $bar; 
    } 
} 

और फिर भी आप $instance->bar का उपयोग करें। लेकिन जब आप $instance->bar = NULL; करते हैं, तो यह $instance->setBar(NULL); पर कॉल करना है।

संबंधित मुद्दे