क्या कोई OO भाषाएँ आधार को कॉल करने के लिए एक ओवरराइड विधि की गारंटी देने के लिए एक तंत्र का समर्थन करती हैं?


12

मुझे लगता है कि यह एक उपयोगी भाषा फीचर हो सकता है और सोच रहा था कि क्या कोई भाषा पहले से ही इसका समर्थन करती है।

यदि आपके पास यह विचार है:

class C
  virtual F
     statement1
     statement2

तथा

class D inherits C
  override F
     statement1
     statement2
     C.F()

सीएफ़ () पर लागू होने वाला एक कीवर्ड होगा, जैसे कि ऊपर कोड की अंतिम पंक्ति को हटाने से एक कंपाइलर त्रुटि होगी, क्योंकि यह कह रहा है कि "इस पद्धति को ओवरराइड किया जा सकता है, लेकिन यहां कार्यान्वयन को कोई फर्क नहीं पड़ता है"।


जवाबों:


14

हाँ, वो करते हैं। इसे OO का स्कैंडिनेवियाई मॉडल कहा जाता है, इसका उपयोग सिमुला में किया जाता है (अन्य OO मॉडल जो कि व्यापक है और अब दिए गए अनुसार लिया गया है, अमेरिकी मॉडल है)। स्कैंडिनेवियाई मॉडल में, आप ओवरराइड नहीं कर रहे हैं, लेकिन उप-व्यवहार की आपूर्ति कर रहे हैं।

सुपरक्लास की विधि फू में:

some-code-before
INNER // this is the actual Simula keyword
some-code-after

उपवर्ग विधि फू में:

some-code-in-subclass

यदि आप सुपरक्लास 'इंस्टेंस' विधि को फू कहते हैं, तो केवल some-code-beforeऔर some-code-afterहोता है ( INNERकुछ नहीं करता है), लेकिन यदि आप सबक्लास के इंस्टेंस को फू कहते हैं, तो यह होता है some-code-before, some-code-in-subclassऔर फिर some-code-after


9

कोई भी भाषा जिसे मैं ओवरराइड विधि को लागू करने के लिए लागू करने के बारे में नहीं जानता। वास्तव में, कुछ भाषाएं ओवरराइडिंग विधियों की अनुमति देती हैं जो कि अधिक उपयोग करने योग्य नहीं हैं (जैसे कि newC # में कीवर्ड का उपयोग करना )। हालाँकि, इसके करीब आने के दो तरीके हैं।

पहला एक अयोग्य विधि का निर्माण करना है (जैसे कि एक जिसमें virtualC # में कीवर्ड की कमी होती है या एक जिसमें finalजावा में कीवर्ड होता है) एक अतिव्यापक कॉल करता है जिसे क्लास के बाहर से नहीं बुलाया जा सकता (जैसे protectedC #, Java या C ++ में)।

class C
  A
     statement1
     F
     statement3

  protected virtual F
     statement2

तथा

class D inherits C

  protected override F
     statement4
     C.F()

Cओवरराइड करने वाली कक्षाएं Fइसके व्यवहार को ओवरराइड करने और संशोधित करने के लिए स्वतंत्र हैं लेकिन क्लास के बाहर से कॉल करने वाले केवल इसके माध्यम से एक्सेस करते हैं A

संपादित करें: जैसा कि अन्य ने बताया है, इसे टेम्प्लेट विधि कहा जाता है ।

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


2
आप privateC ++ में ओवरराइड होने की विधि भी बना सकते हैं :) हर्ब सटर इसे यहाँ विस्तार से बताते हैं ।
fredoverflow

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

7

वास्तव में भाषा का हिस्सा नहीं है, लेकिन जावा के लिए फाइंडबग्स स्टैटिक कोड एनालाइज़र में एक एनोटेशन है OverrideMustInvokeजिसे एक डेवलपर एक विधि में जोड़ सकता है, और जो सुपरबाइंडिंग कॉल न करने वाली एक अतिव्यापी विधि का पता लगाने पर FindBugs को एक त्रुटि दिखाएगा। । यह निर्दिष्ट करने की भी अनुमति देता है कि ओवरराइडिंग विधि में कॉल पहले या अंतिम होना चाहिए या नहीं।


6

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

एक तरीका है जो सभी OO भाषाओं में समर्थित है: टेम्पलेट विधि पैटर्न । यहाँ, आप सुपरक्लास पद्धति को अधिक उपयोग योग्य नहीं बनाते हैं, और इसमें आप एक अति-उपयोगी विधि कहते हैं। उपवर्ग तो कार्यक्षमता जोड़ने के लिए इस विधि को ओवरराइड कर सकता है:

class super {
  public final void doSomething() {
    doSpecialthing();
    doMore();
  }
  public void doSpecialthing() {
  }
}

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


1

निकटतम पैटर्न जिसके बारे में मैं सोच सकता हूँ, वह स्व-सब्सक्राइब की गई घटनाएँ हैं। यह थोड़ा बोझिल है, और कोडर के लिए बिल्कुल सहज नहीं है, लेकिन लक्ष्य को प्राप्त करता है।

class C
{
    public void F()
    {
        ...
        OnF()
    }

    protected event OnF
}

class D : C
{
    public D()
    {
        base.OnF += this.F
    }

    private void F
    {
        ...
    }
}

1
यह एक काफी सामान्य डिजाइन पैटर्न है, कभी-कभी प्रो और पोस्ट दोनों के साथ ओवरराइड जैसे। ViewWillAppear (), ViewDidAppear ()। आदर्श जब आप उपवर्गों को (संशोधित करने के बजाय) डिफ़ॉल्ट व्यवहार को विस्तारित करने की अनुमति देना चाहते हैं।
क्रिस वान बाल

1

लिस्प मशीन "जायके" की अनुमति देता है "विरासत" और "आसपास" के बाद "मुख्य विधि" टाइप करें।


0

जबकि सिद्धांत में एक बुरा विचार नहीं है, इसे लागू करने पर मेरे विकल्पों को विवश करने का नकारात्मक पक्ष-प्रभाव है D। उदाहरण के लिए, क्या होगा अगर (कुछ अथाह कारण के लिए), यह Fकिसी अन्य विधि से सुपरक्लास कार्यान्वयन को कॉल करने के लिए अधिक सुविधाजनक है :

class D inherits C
    override F
        statement1
        statement2
        G()
    G
        statement3
        C.F()
        statement4

अपने परिदृश्य के तहत, मैं कल्पना संकलक ध्वज के कार्यान्वयन होगा Fमें Dहै, भले ही यह होता है (परोक्ष रूप से) कॉल C.F()

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


1
-1: ऐसी स्थिति के बारे में सोचने में सक्षम होना, जहाँ आप उपयोग नहीं करना चाहेंगे, जो इस सवाल का जवाब नहीं है "क्या कोई भाषा इसकी अनुमति देती है"।

@GrahamLee: बहुत सच। मेरी बात एक कारण और समझाने की थी कि कोई भी भाषा (जो मुझे पता है) ऐसी सुविधा को लागू करती है। मुझे लगता है कि मैं समझाने में इतना फंस गया, कि मैं यह बताना भूल गया कि मैं इसे क्यों समझा रहा था। -1 खुशी से स्वीकार किया। :)
मैक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.