2010-07-15 11 views
6

में समान हस्ताक्षर के साथ निजी विधियों की घोषणा करनी होगी, मैं PHP 5.3 का उपयोग कर रहा हूं, और हां, इसके लिए bug open है, लेकिन कुछ सोचते हैं कि यह एक बग नहीं है, और इससे यह होता है मुझे आश्चर्य है।यह एक php बग है: उप-वर्गों को मूल वर्ग

abstract class A{ 
    private function bobo(array $in){ 
    //do something 
    } 
} 

class B extends A{ 
    private function bobo($shmoo,$shmaa){ 
    //do something 
    } 
} 

यह एक त्रुटि फेंकता है। विरासत निजी तरीकों को नजरअंदाज नहीं करना चाहिए ?!

'Declaration of B::bobo() should be compatible with that of A::bobo()'

उत्तर

0

मुझे लगता है कि यह भाषा का एक डिज़ाइन निर्णय है। जावा भाषा डेवलपर्स ने फैसला किया कि यह संभव होना चाहिए।

+1

:-) यह मुझे लगता है जैसे कोई कुछ लागू करने के लिए भूल रहा था। –

+0

जावा में यह विधि भिन्न है क्योंकि विधि हस्ताक्षर विधि नाम, और पैरामीटर प्रकार के होते हैं। PHP हस्ताक्षर में विधि का नाम है क्योंकि आप अतिरिक्त पैरामीटर के साथ विधियों को कॉल कर सकते हैं और विधि के अंदर अतिरिक्त पैरामीटर तक पहुंच सकते हैं। तो PHP केवल फ़ंक्शन के लिए आवश्यक न्यूनतम तर्कों को बता सकता है, लेकिन अब नहीं। – Jari

+0

निजी विधि उप वर्ग में दिखाई नहीं देनी चाहिए (अपने नमूना कोड के मेरे परीक्षा परिणाम देखें)। तो विभिन्न तरीकों से विधि हस्ताक्षर परिभाषित किए गए हैं महत्वपूर्ण नहीं है। –

0

निजी तरीकों निश्चित रूप से विरासत द्वारा नजरअंदाज कर दिया नहीं किया जाना चाहिए, उदाहरण के टेम्पलेट विधि पैटर्न के लिए विचार करना है जहाँ आप एक व्युत्पन्न वर्ग में एक समारोह के व्यवहार को ओवरराइड सकता है, लेकिन माता-पिता वर्ग अभी भी उस समारोह

public class Parent { 
    public final function doThings() { 
     $this->initialize(); 
     $this->customStuff(); 
     $this->cleanup(); 
    } 

    private final function initialize() { 
     // initialize processing 
    } 

    private final function cleanup() { 
     // cleanup processing 
    } 

    private function customStuff() { 
     // parent specific processing 
    } 
} 

public class Derived extends Parent { 
    private function customStuff() { 
     parent::customStuff(); 
     // + derived class specific processing 
    } 
} 

कॉलिंग कॉल कर सकते हैं व्युत्पन्न वर्ग उदाहरण पर DoThings विधि माता-पिता विशिष्ट प्रसंस्करण करेगा, लेकिन निजी तरीकों को ओवरराइड करने की संभावना के कारण गैर-अंतिम अभिभावक वर्ग कस्टमस्टफ विधि द्वारा प्रदान किए गए एक्सटेंशन बिंदु का लाभ उठाना अभी भी संभव है।

संपादित करें: PHP विधि हस्ताक्षर में केवल विधि का नाम होता है क्योंकि आप शून्य पैरामीटर लेने वाली विधि को परिभाषित कर सकते हैं और फिर भी इसे कई पैरामीटर के साथ कॉल कर सकते हैं। फ़ंक्शन func_get_args फ़ंक्शन का उपयोग करके तर्कों तक पहुंच सकता है।

+1

लेकिन आप ** ** व्युत्पन्न :: कस्टमस्टफ में पैरामीटर जोड़ नहीं सकते हैं। मुझे खेद है, लेकिन मुझे नहीं लगता कि आपका उदाहरण मेरे प्रश्न से कैसे संबंधित है। –

+0

आपने पूछा कि क्या विरासत निजी तरीकों को अनदेखा करनी चाहिए या नहीं, मैंने एक उदाहरण दिया है कि उन्हें – Jari

+0

$ व्युत्पन्न = नया व्युत्पन्न(); $ Derived-> doThings(); माता-पिता की customStuff() विधि निष्पादित करेगा और व्युत्पन्न में से एक नहीं। –

5

ध्यान दें कि बग रिपोर्ट थोड़ी दूर है, क्योंकि PHP इस संदेश को तब भी लॉग करेगा जब आपके पास E_STRICT का त्रुटि स्तर होगा (या हाल ही में, आपके त्रुटि स्तर पर ध्यान दिए बिना कि आपने एक कस्टम त्रुटि हैंडलर सेट किया है) ।

PHP का visibility rules स्पष्ट रूप से दर्शाता है कि एक बच्चे को अपने माता-पिता के निजी सदस्यों को देखने की क्षमता नहीं है, जो मुझे संदेह है कि किसी के लिए आश्चर्य की बात है। अगर बच्चा अपने माता-पिता के तरीकों को नहीं देख पा रहा है, तो मुझे समझ में नहीं आता कि उनकी परिभाषाओं का पालन करने के लिए इसका कर्तव्य कैसे हो सकता है।

मैं व्यक्तिगत रूप से लगता है कि बग के कारण है कि यह नहीं था कोई वास्तविक दोष (क्योंकि यह गैर स्पष्ट है और मैं दस्तावेज में यह किसी भी उल्लेख नहीं पा सके) किसी भी विवरण के बिना के रूप में फर्जी चिह्नित किया जा रहा एक है थोड़ा गलत, लेकिन हाँ। यही कारण है कि एक तरफ, मैं zend_compile.c में राय लाइन 2669 की कर रहा हूँ वास्तव में इस प्रकार है पढ़ना चाहिए:

} else if (child->prototype && 
    (EG(error_reporting) & E_STRICT || EG(user_error_handler))) { 

... जो त्रुटि पॉपिंग से बचने होगा जब माता-पिता की विधि निजी चिह्नित किया गया था। यह देखते हुए कि आपके पास हमेशा E_STRICT लॉगिंग नहीं करने का विकल्प है, और यह वास्तव में कुछ भी नकारात्मक प्रभाव नहीं डालता है, मुझे लगता है कि यह वास्तव में एक बड़ा सौदा नहीं है। मैं निश्चित रूप से नहीं देखता कि यह जानबूझकर कैसे हो सकता है, लेकिन मैं एक PHP इंजन डेवलपर नहीं हूं।

2

मुझे लगता है कि यहां दो संभावनाएं हैं। या तो यह एक बग है या PHP.net/manual पर प्रलेखन गलत है। PHP मैनुअल के तीन खंड यहां दिए गए हैं।सबसे पहले विरासत पर:

Object Inheritance

Inheritance is a well-established programming principle, and PHP makes use of this principle in its object model. This principle will affect the way many classes and objects relate to one another.

For example, when you extend a class, the subclass inherits all of the public and protected methods from the parent class. Unless a class overrides those methods, they will retain their original functionality.

This is useful for defining and abstracting functionality, and permits the implementation of additional functionality in similar objects without the need to reimplement all of the shared functionality.

और पर सार कक्षाएं:

Class Abstraction

PHP 5 introduces abstract classes and methods. It is not allowed to create an instance of a class that has been defined as abstract. Any class that contains at least one abstract method must also be abstract. Methods defined as abstract simply declare the method's signature they cannot define the implementation.

When inheriting from an abstract class, all methods marked abstract in the parent's class declaration must be defined by the child; additionally, these methods must be defined with the same (or a less restricted) visibility. For example, if the abstract method is defined as protected, the function implementation must be defined as either protected or public, but not private.

अंत में, इंटरफेस

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

मेरी राय है कि ...

1

बग रिपोर्ट जब आप इंटरफ़ेस को दूर उसमें कोई त्रुटि नहीं है में। यह इसे "अधिक" अजीब व्यवहार बनाता है क्योंकि इंटरफ़ेस बस खाली है।

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