2012-01-27 21 views
11
फेंकता

मेरे Parent वर्ग है:विरासत, विधि हस्ताक्षर, विधि अधिभावी और खंड

public class Child1 extends Parent{ 
    public int getX(){ 
     return x+10; 
    } 
} 

सूचना जबकि अधिभावीgetX:

import java.io.IOException; 
public class Parent { 
     int x = 0; 
     public int getX() throws IOException{ 
     if(x<=0){ 
     throw new IOException(); 
     } 
     return x; 
     } 
} 

मैं extend इस वर्ग के एक उपवर्ग Child लिखने के लिएChild कक्षा में विधि, मैंने विधि परिभाषा से throws खंड हटा दिया है। अब यह संकलक द्वारा एक विषम व्यवहार में परिणाम जो उम्मीद है:

new Parent().getX() ; 

एक try-catch ब्लॉक में यह enclosing के बिना संकलन नहीं करता है, के रूप में उम्मीद।

new Child().getX() ; 

एक try-catch ब्लॉक में यह enclosing के बिना संकलित करता है।

लेकिन कोड की निम्न पंक्तियों को ट्राइक-कैच ब्लॉक की आवश्यकता है।

Parent p = new Child(); 
p.getX(); 

इस रन-टाइम बहुरूपता के दौरान एक बच्चे विधि आह्वान करने के लिए एक माता पिता के वर्ग संदर्भ का उपयोग कर यानी अनुमान किया जा सकता है के रूप में, क्यों जावा के डिजाइनरों यह विधि परिभाषा थोड़ी देर में खंड फेंकता शामिल करने के लिए अनिवार्य नहीं किया एक विशेष पेरेंट क्लास विधि ओवरराइडिंग? मेरा मतलब है कि अगर एक अभिभावक वर्ग विधि ने अपनी परिभाषा में खंड फेंक दिया है, तो इसे ओवरराइड करने के दौरान ओवरराइडिंग विधि में थ्रो क्लॉज भी शामिल होना चाहिए, है ना?

+0

अपने अंतिम वाक्य में, "तो, जबकि यह अधिभावी *** अधिभावी *** विधि (उपवर्ग में विधि) भी खंड फेंकता शामिल होना चाहिए" क्या आपका मतलब ??? – Bhushan

उत्तर

25

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

Parent के संदर्भ के माध्यम से ओवरराइड विधि का उपयोग करना कभी भी "फेंक सकता है" के अनुबंध का उल्लंघन नहीं करेगा "- अपवाद की अनुपस्थिति अनुबंध का उल्लंघन नहीं करती है। दूसरी तरफ गोल (यदि माता-पिता अपवाद घोषित नहीं किया गया है, लेकिन ओवरराइडिंग विधि करता है) अनुबंध उल्लंघन हो।

+0

मुझे प्रबुद्ध करने के लिए धन्यवाद :) – NINCOMPOOP

+0

आप जॉन के जवाब को स्वीकार कर सकते हैं :) – Bhushan

+0

'ताकि यह उन कॉलर्स को आश्चर्यचकित नहीं कर सके जो अभिभावक घोषणा के माध्यम से इसे एक्सेस करते हैं।' यह वास्तव में तर्क को समझने में मेरी मदद की। –

3

ठीक है, ओवरराइडिंग विधि किसी भी अपवाद को कम नहीं कर सकती है (या कम से कम कम अपवाद), इस प्रकार आप फेंक क्लॉज (या पूरी तरह से फेंक क्लॉज) से अपवाद हटा सकते हैं।

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

अपवाद जोड़ना काम नहीं करेगा, क्योंकि Parent संदर्भ के माध्यम से इसे एक्सेस करने वाले वर्ग के उपयोगकर्ता Child किसी भी अपवाद के बारे में नहीं जानते हैं।

2

आपके पास फेंकता कीवर्ड के बिना किसी विधि को ओवरराइड करने की स्वतंत्रता है, क्योंकि यदि आप सभी अपवादों को नियंत्रित करके एक विधि विकसित करना चाहते हैं, तो आप बिना किसी फेंकने वाले विधि को ओवरराइड करके ऐसा कर सकते हैं।

लेकिन एक बात याद रखें कि यदि आप सबक्लास विधि में फेंकने वाले खंड को शामिल करना चाहते हैं, तो फेंकने वाले खंड को अपवाद के साथ जोड़ना चाहिए जो कि इसके सुपरक्लास विधि द्वारा अपवादित अपवाद के समान या उप-वर्ग होना चाहिए। उदाहरण के

class Super{ 
    void a()throws IOException{ 
     ...... 
    } 
} 
class Sub extends Super{ 
    void a()throws IOException{ 
     ...... 
    } 
} 

के लिए एक() वर्ग उप की विधि, IOException या IOException में से किसी उपवर्ग फेंक जाना चाहिए, अन्यथा संकलक त्रुटि दिखाई देगा।

इसका मतलब है कि यदि आप लिखना

void a()throws Exception 
वर्ग उप में

, तो यह संकलन त्रुटि का कारण होगा।

2

आसान

  1. पहुँच संशोधक कम प्रतिबंधित करने के लिए प्रतिबंधित से बदला जा सकता है याद करने के लिए, उदाहरण के लिए
    जनता के लिए संरक्षित से नहीं, बल्कि विपरीत शिकंजा
  2. फेंकता हस्ताक्षर बच्चे को माता-पिता अपवाद से परिवर्तन किया जा सकता है अपवाद वर्ग नहीं, बल्कि विपरीत शिकंजा

इस कोड को मान्य है

public class A { 

    protected String foo() throws Exception{ 
     return "a"; 
    } 

    class B extends A { 
     @Override 
     public String foo() throws IOException{ 
      return "b"; 
     } 
    } 
} 

Overrided foo विधि सार्वजनिक उपयोग, सुरक्षित नहीं है और IOException अपवाद की है कि बच्चे फेंकता

यह कोड मान्य नहीं है

public class A { 

    public String foo() throws IOException{ 
     return "a"; 
    } 

    class B extends A { 
     @Override 
     protected String foo() throws Exception{ 
      return "b"; 
     } 
    } 
} 

Overrided foo विधि अधिक प्रतिबंधित एक्सेस संशोधक है और फेंकता अपवाद है कि नहीं बच्चे IOException

की

जिस तरह से आप सुपर क्लास से विधि ओवरराइड कर सकते हैं और सभी

यह ग पर ecxeptions फेंक नहीं करके स्तोत्र वैध

public class A { 

    public String foo() throws IOException{ 
     return "a"; 
    } 

    class B extends A { 
     @Override 
     public String foo(){ 
      return "b"; 
     } 
    } 
} 
+0

इससे मदद मिलती है, इस सवाल के कारण साक्षात्कार में नष्ट हो गया। – saiki4116

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