2009-05-22 10 views
14

पशु कुत्ते का एक सुपरक्लास है और कुत्ते के पास छालक्या सुपरक्लास ऑब्जेक्ट पर सबक्लास के तरीकों को कॉल करना संभव है?

public void bark() 
{ 
    System.out.println("woof"); 
} 

नामक एक विधि है:

Animal a = new Dog(); 
if (a instanceof Dog){ 
    a.bark(); 
} 

क्या होगा?

  1. असाइनमेंट की अनुमति नहीं है
  2. छाल को कॉल करने की अनुमति है और "woof" को रन टाइम पर मुद्रित किया जाता है
  3. छाल को कॉल करने की अनुमति है लेकिन कुछ भी मुद्रित नहीं है
  4. छाल पर कॉल एक संकलन समय त्रुटि
  5. को रन टाइम त्रुटि में छाल परिणामों के लिए कॉल का कारण बनता है

मैंने कहा 2 क्योंकि हम जांच रहे हैं कि ऑब्जेक्ट एक कुत्ता है या नहीं; चूंकि कुत्ता उस में छाल विधि वाला वर्ग है, यदि यह है तो हम इसे कॉल करेंगे जो प्रिंट करेगा: s

क्या मेरी समझ यहां सही है?

+0

यहां प्रश्न को बदलने का सुझाव है "क्या सुपरक्लास के पास उनके उप-वर्गों के तरीके हैं?" या इसी के समान। –

+1

चाल यह है कि आप यह सुनिश्चित करने के लिए जांच कर रहे हैं कि यह एक कुत्ता है, लेकिन कंपाइलर तार्किक कनेक्शन नहीं बनाता है कि ए.बार्क केवल कुत्ते होने पर ही बुलाया जाएगा। आपको छाल() कॉल के उद्देश्य के लिए कुत्ते की तरह व्यवहार करने के लिए संकलक को स्पष्ट रूप से बताना होगा, जैसे साइमन 622 ने नीचे कहा था। –

+1

संयोग से, यही कारण है कि कई लोग "बतख टाइपिंग" पसंद करते हैं। कहें, पायथन, समकक्ष कोड को यह भी जांचने की आवश्यकता नहीं होगी कि 'ए' एक कुत्ता था या नहीं; जब तक उस लाइन पर पहुंचने पर 'ए' की 'छाल' विधि थी, तो यह काम करेगा। –

उत्तर

31

यह संकलित नहीं होगा क्योंकि पशु में छाल नामक विधि नहीं है। इस तरह से सोचें, सभी कुत्ते जानवर हैं, लेकिन सभी जानवर कुत्ते नहीं हैं। सभी कुत्ते छाल, लेकिन सभी जानवर छाल नहीं।

+6

और इस प्रकार, 4 सही उत्तर है । स्पष्टीकरण जोड़ने के लिए –

25

नहीं - उत्तर है;

4) छाल करने के लिए कॉल एक संकलन समय का कारण बनता है त्रुटि

छाल विधि नहीं है सौंपा प्रकार पशु है, जो इसलिए संकलन समय अंक में परिणाम होगा पर एक तरीके के रूप में परिभाषित किया गया; इसे कास्टिंग द्वारा हल किया जा सकता है;

((Dog)a).bark(); 
4

यह 4 है। आप एक सामान्य पशु से नहीं पूछ सकते - जो कि आपका कोड कहता है - छाल के लिए है। क्योंकि आप आसानी से

Animal a = new Cat(); 

और छाल लाइन के पास यह जानने का कोई तरीका नहीं है कि आपने ऐसा नहीं किया है।

11

कुंजी निम्न पंक्ति में है:

Animal a = new Dog(); 

हालांकि Dog का एक नया उदाहरण बनाया गया था, इसके संदर्भ a किस प्रकार Animal का होना घोषित किया जाता है कर रहा है। इसलिए, a पर कोई भी संदर्भ new Dog को Animal के रूप में संभाला जाता है।

इसलिए, जब तक Animal एक bark विधि है, निम्न पंक्ति एक संकलक त्रुटि का कारण होगा:

a.bark(); 

भी a हालांकि अगर यह Dog का एक उदाहरण है यह देखने के लिए परीक्षण किया जाता है, और a instanceof Dog वास्तव में true वापस आ जाएगी , परिवर्तनीय a अभी भी Animal प्रकार का है, इसलिए if कथन के अंदर ब्लॉक अभी भी a को Animal के रूप में संभालता है।

यह statically-typed languages की एक विशेषता है जहां चर को समय से पहले एक प्रकार असाइन किया जाता है, और यह देखने के लिए संकलन-समय पर जांच की जाती है कि प्रकार मिलान करते हैं। इस कोड को एक dynamically-typed language, जहां प्रकार रनटाइम पर जाँच कर रहे हैं पर प्रदर्शन किया गया है, तो निम्नलिखित की तरह कुछ की अनुमति दी जा सकता है:

var a = new Dog(); 
if (a instanceof Dog) 
    a.bark(); 

a.bark() निष्पादित करने के लिए जब उदाहरण के एक Dog है केवल गारंटी है, इसलिए bark करने के लिए कॉल हमेशा काम करेगा। हालांकि, जावा एक स्थाई रूप से टाइप की गई भाषा है, इसलिए इस प्रकार के कोड की अनुमति नहीं है।

+0

+1: स्थिर रूप से बनाम गतिशील रूप से टाइप की गई भाषाओं। –

+0

क्या होता है यदि दोनों वर्गों में छाल() विधि है, जिसे एक निष्पादित किया जाता है। –

+1

@ राहुल कदुकर: यदि "** पशु ** ** कुत्ते ** का एक सुपरक्लास है", और दोनों वर्गों में ** छाल() ** विधि है, तो ** छाल() ** * * छाल() ** उपclass ** कुत्ते ** में विधि। इस प्रकार, a.bark() ** कुत्ते ** कक्षा में ** छाल() ** विधि निष्पादित करेगा। – NoName

3

Head First Java में वे बहुत अच्छा वस्तु कि संदर्भ बिंदु के रूप में एक संदर्भ के लिए एक टीवी रिमोट कंट्रोल के सादृश्य और अपने टीवी का उपयोग करें। यदि आपके रिमोट में केवल चालू, बंद, चैनल ऊपर और नीचे, और वॉल्यूम ऊपर और नीचे के लिए बटन (विधियां) हैं, इससे कोई फ़र्क नहीं पड़ता कि आपके टीवी में कितनी अच्छी सुविधाएं हैं। आप अभी भी अपने रिमोट से कुछ बुनियादी चीजें कर सकते हैं। आप अपने टीवी को म्यूट नहीं कर सकते, उदाहरण के लिए, यदि आपके रिमोट में म्यूट बटन नहीं है।

पशु संदर्भ केवल पशु विधियों के बारे में जानता है। इससे कोई फर्क नहीं पड़ता कि अंतर्निहित वस्तु के अन्य तरीकों में क्या है, आप उन्हें पशु संदर्भ से नहीं पहुंच सकते हैं।

1

"I said 2 as we are checking if the object is a dog; as dog is the class with the bark method in it, if it is then we call it which will print out :s"

आपका तर्क सही है, लेकिन यह काम नहीं करता है।

जावा एक स्थैतिक टाइप की गई भाषा है जिसका अर्थ है कि किसी ऑब्जेक्ट का जवाब देने वाले तरीकों की वैधता संकलित समय पर सत्यापित की गई है।

आप चेक लगता है हो सकता है:

if(a instanceof Dog) 

करना चाहेंगे, लेकिन वास्तव में ऐसा नहीं है। संकलक क्या घोषित प्रकार (इस मामले में पशु) के "इंटरफ़ेस" के खिलाफ जांच करता है। "इंटरफेस" पशु वर्ग पर घोषित विधियों से बना है।

छाल() विधि सुपर वर्ग पशु संकलक का कहना है के रूप में परिभाषित नहीं किया गया है: "अरे, वह काम नहीं करेंगे।"

यह उपयोगी है क्योंकि "कभी-कभी" हम, जबकि (बजाय उदाहरण के लिए barck (टाइप))

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

फिर भी, जावा जैसी स्थिर टाइप की गई भाषा हमें कॉल को मजबूर करने की अनुमति देती है। इस मामले में यह "डाली" ऑपरेटर()

उपयोग कर रहा है इस

1. Animal a = new Dog(); 
2. if (a instanceof Dog){ 
3.  Dog imADog = (Dog) a; 
4.  imADog.bark(); 
5. } 

लाइन 3 अपने एक कुत्ता प्रकार को "कास्टिंग" कर रहे हैं की तरह है, इसलिए यदि छाल एक वैध संदेश है संकलक जाँच कर सकते हैं।

यह संकलक को यह निर्देश है कि "अरे मैं प्रोग्रामर हूं, मुझे पता है कि मैं क्या कर रहा हूं"। और कंपाइलर, चेक, ओके, कुत्ते, संदेश छाल() प्राप्त कर सकते हैं, आगे बढ़ें। फिर भी, अगर रनटाइम में जानवर कुत्ता नहीं है, तो रनटाइम अपवाद बढ़ जाएगा।

if(a instanceof Dog) { 
    ((Dog)a).bark(); 
} 

कि चलेंगे:

डाली भी तरह संक्षिप्त किया जा सकता है।

तो, सही जवाब 4:

"छाल करने के लिए कॉल एक संकलन समय त्रुटि का कारण बनता है" मुझे आशा है यह मदद करता है।

2

एफवाईआई, यह एक अच्छा डिजाइन नहीं है।

if (x instanceof SomeClass) 
{ 
    x.SomeMethod(); 
} 

आप प्रकार प्रणाली का दुरुपयोग करते हैं:

बस किसी भी समय के बारे में आप इस फार्म के कोड है। यह वर्गों का उपयोग करने का तरीका नहीं है, यह रखरखाव ऑब्जेक्ट उन्मुख कोड लिखने का तरीका नहीं है। यह भंगुर है। यह घुल गया है। यह बुरा है।

आप बेस क्लास में टेम्पलेट विधियां बना सकते हैं, लेकिन उन्हें बेस क्लास में मौजूद विधियों को कॉल करना होगा और उप-वर्गों में ओवरराइड किया जाना चाहिए।

4

विचार सुपर क्लास वस्तु से उपवर्ग विधि मुद्रित करने के लिए है, तो यह काम करेगा:

इसके बजाय Animal a = new Dog(); if (a instanceof Dog){ a.bark(); } परिवर्तन की को

Animal a = new Dog(); 

if (a instanceof Dog){ 
    Dog d = (Dog) a; 
    d.bark(); 
} 

इस सुपर क्लास वापस उपवर्ग और यह प्रिंट करने के लिए डाले। हालांकि इसकी खराब डिज़ाइन, यह जानने का एक तरीका है कि कौन सा बाल वर्ग गतिशील रूप से इंगित करता है।

+0

या, यदि आपको ऐसा कुछ करना है, तो आप 'अगर (उदाहरण के कुत्ते) {((कुत्ते) ए) कर सकते हैं। बार्क(); } ' – GreenMatt

2

जावा में (केवल भाषा मुझे पता है) आप एक खाली विधि बना सकते हैं और इसे सुपर क्लास में कॉल कर सकते हैं। फिर आप इसे जो कुछ भी चाहते हैं उसे करने के लिए उप-वर्ग में इसे ओवरराइड कर सकते हैं। इस तरह सुपर क्लास अपनी सबक्लास 'विधि को कॉल करता है।

public class Test { 
    public static void main(String[] args){ 
     Snake S = new Snake(); 
     Dog d = new Dog(); 
    } 
} 


class Animal{ //Super Class 
    public Animal(){ 
     bark(); //calls bark when a new animal is created 
    } 
    public void bark(){ 
     System.out.println("this animal can't bark"); 
    } 
} 



class Dog extends Animal{ //Subclass 1 
    @Override 
    public void bark(){ 
     System.out.println("Woof"); 
    } 
} 



class Snake extends Animal{//Subclass 2 
    public void tss(){ 
    } 
} 

यह कोड सांप की एक वस्तु को कॉल करता है और फिर कुत्ते की वस्तु को बुलाता है।यह कंसोल को लिखता है:

this animal can't bark 
Woof 

सांप में कोई छाल विधि नहीं है इसलिए सुपर क्लास 'विधि कहा जाता है। यह कंसोल की पहली पंक्ति लिखता है। कुत्ते के पास छाल विधि है इसलिए सुपर क्लास इसके बजाय कॉल करता है। यह कंसोल के लिए दूसरी पंक्ति लिखता है।

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

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