2015-10-04 10 views
6

के अनुसार कॉल करने के लिए बल ओवरराइड विधि मुझे इस उपयोग के मामले में एक सामान्य समस्या है: मेरे पास कक्षा A है। इस वर्ग में एक गैर-अमूर्त विधि doStuffCallback() है जिसे ओवरराइड किया जा सकता है लेकिन यह प्रत्येक उप-वर्ग के लिए आवश्यक नहीं है। लेकिन: मैं यह सुनिश्चित करना चाहता हूं कि यदि विधि ओवरराइड हो जाती है तो सबक्लास-विधि को माता-पिता विधि को कॉल करना होगा।ओओपी (PHP) - पैरेंट-विधि

उदाहरण:

abstract class A { 
    private function doStuff() { 
     $this->doStuffCallback(); 
    } 

    protected function doStuffCallback() { 
     // IMPORTANT CODE HERE 
    } 
} 

class B extends A { 
    protected function doStuffCallback() { 
     parent::doStuffCallback(); // I want to enforce this because the parents method code is important 

     // ALSO IMPORTANT CODE 
    } 
} 

क्योंकि ओवरराइड विधि एक ही बात यह एक ही जिम्मेदारी के लिए दो तरीकों और एक निजी सहायक-विधि है जो दोनों कॉल को परिभाषित करने के बहुत बदसूरत होगा करता है। इस तरह:

abstract class A { 
    private function doStuff() { 
     $this->callDoStuffCallback(); 
    } 

    private function callDoStuffCallback() { 
     $this->internalDoStuffCallback(); 
     $this->doStuffCallback(); 

     // This is VERY ugly 
    } 

    private function internalDoStuffCallback() { 
     // IMPORTANT CODE HERE 
    } 

    protected function doStuffCallback() {} 
} 

class B extends A { 
    protected function doStuffCallback() { 
     // IMPORTANT CODE 
    } 
} 

यह वास्तव में बदसूरत और श्रमिक है। तो मेरा प्रश्न: क्या माता-पिता विधि को कॉल करने के लिए अतिव्यापी तरीकों को बल देने के लिए PHP में कोई तरीका है?

उत्तर

6

नहीं। ऐसा कोई भाषा विशेषता है PHP में; अधिकांश उप-प्रकार-'OO 'भाषाओं में यह प्रतिबंध संभव नहीं है।

इसके बजाय कार्यक्रमों को स्पष्ट दस्तावेज़ीकरण अनुबंधों पर भरोसा करना चाहिए; और उम्मीद है कि अनुरूपता सुनिश्चित करने के लिए इकाई परीक्षण।


गार्ड भी इस तरह के नियोजित किया जा सकता है कि, द्वारा और जब जनक वर्ग पर एक विधि का इस्तेमाल किया जाता है के द्वारा कुछ बिंदु पर, यह एक अपवाद है, तो 'वर्तमान स्थिति' मान्य नहीं है फेंक सकता है (उदाहरण के लिए। इस तरह के और ऐसी विधि अभी तक नहीं बुलाई गई है)। उपरोक्त सुपर विधि की बजाय, कुछ विशेष विधि को कॉल करने के लिए आवश्यक उपclass (जैसा कि प्रलेखन अनुबंध में परिभाषित किया गया है) को बनाकर इसे और अधिक स्पष्ट किया जा सकता है। हालांकि, यह किसी भी प्रकार की प्रणाली के बाहर है।

self:: गुंजाइश इस्तेमाल किया जा सकता है (। उदाहरण के लिए फोन गैर ओवरराइड विधि है जो ओवरराइड प्रणाली को बुलाती है), इस आगे जादू शामिल होगा अनंत प्रत्यावर्तन छोरों से बचने के लिए (जैसे कुछ ढेर राज्य।); और यह आकस्मिक रूप से उपयोग को छोड़ना आसान होगा।

मेरी सिफारिश एक (निजी) विधि को कॉल करना है जो कि जो भी तर्क लागू होता है, के संबंध में इस 'शायद अतिरंजित' विधि को कॉल करता है, जैसा कि उदाहरण में दिखाया गया है (हालांकि उम्मीद है कि अधिक कार्य विशिष्ट टेम्स के साथ)। फिर (संरक्षित) अतिरंजित विधि की अपेक्षा नहीं की जाती है या किसी भी विशेष तर्क को संभालने की आवश्यकता नहीं होती है; न ही यह मूल वर्ग द्वारा स्थापित संदर्भ के बाहर सीधे कहा जाता है - यह वही है जो वर्तमान में दावा करता है, एक विशेष कॉलबैक।

+0

आपके उत्तर के लिए धन्यवाद! मुझे बिल्कुल वही लगता है। मेरा मानना ​​है कि आजकल हम जिस ओओपी का उपयोग करते हैं वह अभी तक पूरा नहीं हुआ है। ऐसे कई पहलू हैं जो महत्वपूर्ण हैं लेकिन संभाले नहीं जाते हैं। –

-2

नहीं, आप उपयोग कर सकते हैं, तो आप इस

<?php 

class A { 

    function s1($p1) { 
     echo 's1: '.$p1; 
    } 
} 


class B extends A { 

    public function callParent($method, $p1) { 
     parent::$method($p1); 
    } 
} 


$b = new B(); 

$b->callParent('s1', 'param1'); 

की तरह, माता पिता के लिए विधि का उपयोग करें या जादू तरीकों __call पर विस्तार जगह ले सकता है और आदि https://github.com/StagnantIce/php_extend_magic/blob/master/AExtendClass.php

+0

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

2

मैं "यह बहुत बदसूरत" से असहमत हैं। यह इस उपयोग के मामले को संभालने का मानक तरीका है और Template Method Pattern का एक संस्करण है।

अब मैं अनुमान लगा रहा हूं क्योंकि आपने वास्तविक उदाहरण प्रदान नहीं किया है, लेकिन यदि आप कहते हैं कि दो विधियां "एक ही काम करती हैं", तो आपके डिजाइन में कुछ गड़बड़ हो सकती है। यदि वे एक ही काम करते हैं, तो सबक्लास एक अलग तरीके से एक ही काम करता है तो माता-पिता को आवश्यक कार्यान्वयन क्यों जरूरी है?मेरे लिए ऐसा लगता है कि विधि वास्तव में एक से अधिक चीज़ करता है और आप इसे कई हिस्सों में तोड़ने में सक्षम हो सकते हैं जिन्हें अलग-अलग ओवरराइड किया जा सकता है (या नहीं, फिर उन्हें निजी या अंतिम बनाएं)।

+0

हां, "वही बात" यहां सही शब्द नहीं है। इन विधियों की एक ही ज़िम्मेदारी है लेकिन उप-वर्ग-विधि इसे अपनी अतिरिक्त आवश्यकताओं के लिए विस्तारित करती है। –

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