php में मूल विधि को कॉल करने के कई तरीके


90

पहले मैं उलझन में था कि दोनों विधायक निर्माण कार्य में क्यों बुलाते हैं, लेकिन अब मुझे लगता है कि मैं समझता हूं। फैली हुई कक्षाएं माता-पिता के तरीकों को विरासत में देती हैं जैसे कि उन्हें कक्षा में ही घोषित किया गया था, और वे तरीके माता-पिता में मौजूद हैं, इसलिए दोनों को काम करना चाहिए।

अब मैं सोच रहा हूं कि क्या विधि (द्वारा parentया this) कॉल करने का एक पसंदीदा तरीका (अर्थात सर्वोत्तम अभ्यास) है , और क्या ये वास्तव में एक ही कोड को निष्पादित करने के समान तरीके हैं या नहीं, या यदि कोई एक ओवर का उपयोग करते समय कोई भी चेतावनी है या नहीं अन्य।

क्षमा करें, मैं शायद यह सोच रहा हूं।

abstract class Animal {

    function get_species() {

        echo "test";

    }

}

class Dog extends Animal {

    function __construct(){

        $this->get_species();
        parent::get_species();

    }

}

$spike = new Dog;

जवाबों:


120

वहाँ तीन परिदृश्य हैं (जो मैं सोच सकता हूं) जहां आप उप-विधि में एक विधि को कॉल करेंगे जहां विधि मूल श्रेणी में बाहर निकलती है:

  1. उपवर्ग द्वारा विधि अधिलेखित नहीं है, केवल माता-पिता में मौजूद है।

    यह आपके उदाहरण के समान है, और आमतौर पर इसका उपयोग करने के लिए बेहतर है $this -> get_species(); आप सही हैं कि इस मामले में दोनों प्रभावी रूप से समान हैं, लेकिन विधि को उपवर्ग द्वारा विरासत में मिला है, इसलिए अंतर करने का कोई कारण नहीं है। उपयोग करके $thisआप विरासत में मिली विधियों और स्थानीय रूप से घोषित तरीकों के बीच बने रहते हैं।

  2. विधि उपवर्ग द्वारा अधिलेखित है और माता-पिता से पूरी तरह से अद्वितीय तर्क है।

    इस मामले में, आप स्पष्ट रूप से उपयोग करना चाहते हैं $this -> get_species();क्योंकि आप निष्पादित विधि का मूल संस्करण नहीं चाहते हैं। फिर से, लगातार उपयोग करके $this, आपको इस मामले और पहले के बीच अंतर के बारे में चिंता करने की आवश्यकता नहीं है।

  3. विधि पैरेंट क्लास को बढ़ाती है, जो कि पेरेंट मेथड को प्राप्त करता है।

    इस मामले में, आप अभी भी `$this -> get_species();उपवर्ग के अन्य तरीकों से विधि को कॉल करते समय उपयोग करना चाहते हैं । एक जगह जिसे आप मूल विधि कहेंगे, वह उस विधि से होगी जो मूल विधि को अधिलेखित कर रही है। उदाहरण:

    abstract class Animal {
    
        function get_species() {
    
            echo "I am an animal.";
    
        }
    
     }
    
     class Dog extends Animal {
    
         function __construct(){
    
             $this->get_species();
         }
    
         function get_species(){
    
             parent::get_species();
             echo "More specifically, I am a dog.";
         }
    }
    

एकमात्र परिदृश्य मैं कल्पना कर सकता हूं कि आपको ओवरराइडिंग पद्धति के बाहर सीधे पैरेंट विधि को कॉल करने की आवश्यकता होगी यदि वे दो अलग-अलग चीजें करते थे और आप जानते थे कि आपको स्थानीय नहीं बल्कि विधि के माता-पिता के संस्करण की आवश्यकता है। यह मामला नहीं होना चाहिए, लेकिन अगर यह स्वयं उपस्थित होता है, तो यह दृष्टिकोण करने का साफ तरीका एक नाम के साथ एक नई विधि बनाना होगा, get_parentSpecies()जहां यह सब करता है, मूल विधि कहलाती है:

function get_parentSpecies(){

     parent::get_species();
}

फिर, यह सब कुछ अच्छा और सुसंगत रखता है, जो मूल पद्धति पर निर्भर होने के बजाय स्थानीय पद्धति में परिवर्तन / संशोधन की अनुमति देता है।


मैं इसे "विस्तार" के बिना कैसे करूंगा? जैसे मेरे पास क्लास "मानव" के अंदर कुछ क्लैस "लेग" है, लेकिन मुझे वास्तव में इसे विस्तारित करने की आवश्यकता नहीं है, क्योंकि मुझे माता-पिता की "मानव" कार्यक्षमता की आवश्यकता नहीं है। अब, अगर मैं $leg = new leg()अंदर का निर्माण करता हूं, तो मैं humanएक पैर उदाहरण के अंदर से मानव कार्यों को कैसे कहूंगा $leg?
user151496

@ user151496 एक पैर मानव का एक उपवर्ग नहीं है। एक मानव के कई पैर होते हैं, लेकिन एक पैर मानव का एक प्रकार नहीं है। इसलिए आपके पास पैर का एक वर्ग नहीं होना चाहिए जो मानव से विरासत में मिला है, क्योंकि एक पैर मानव नहीं है।
बीटल

क्या आप लेग को एक ऐसा वर्ग बनाएंगे जिसमें लेग्गी का एक इंटरफ़ेस है? या सिर्फ ह्यूमन क्लास ने लेग्गी को लागू किया है? हम कैसे सबसे अच्छा परिभाषित कर सकते हैं कि एक पैर मनुष्यों के लिए अनन्य नहीं है, लेकिन यह भी कि मानव पैर विशिष्ट रूप से मानव और मनुष्यों की एक सामान्य संपत्ति है?
एंथोनी

2
पैमायम नीकुडोटायम थोड़ा भ्रमित करने वाला है। पहली नज़र में ऐसा लगता है जैसे आप एक स्टैटिक विधि कह रहे हैं। यह माता-पिता होना चाहिए था
पेटेरुला

माना। कई मामलों में स्टेटिक कॉल बहुत भ्रामक हैं। मुझे कुछ बिंदु पर यह अद्यतन करना चाहिए।
एंथनी

5

जब तक मैं इस प्रश्न को गलत नहीं समझता, मैं लगभग हमेशा इस $ का उपयोग करता हूँ- get_species क्योंकि उपवर्ग (इस मामले में कुत्ते) उस पद्धति को अधिलेखित कर सकता है क्योंकि यह इसे विस्तारित करता है। यदि क्लास डॉग विधि को फिर से परिभाषित नहीं करता है, तो दोनों तरीके कार्यात्मक रूप से समतुल्य हैं, लेकिन यदि भविष्य में किसी बिंदु पर आप यह तय करते हैं कि कुत्ते में get_species विधि "कुत्ते" को प्रिंट करनी चाहिए, तो आपको सभी कोड के माध्यम से वापस जाना होगा बदल दें।

जब आप $ का उपयोग करते हैं तो यह वास्तव में आपके द्वारा बनाई गई वस्तु का हिस्सा होता है और इसलिए हमेशा सबसे अद्यतित रहेगा (यदि उपयोग की जा रही संपत्ति वस्तु के जीवनकाल में किसी तरह बदल गई है) तो मूल वर्ग का उपयोग करते समय स्थैतिक वर्ग विधि को बुला रहा है।


अगर मैं इस विधि को ओवरराइड करना चाहता हूं तो $ इस का उपयोग करने के बारे में यह एक अच्छा बिंदु है। साभार
जेरी २
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.