2010-06-05 21 views
6

क्या कोई निम्नलिखित कोड के काम को समझा सकता है ...?क्या कोई निम्नलिखित कोड के काम को समझा सकता है ...?

interface myInterface{} 

public class Main { 

    public static void main(String[] args) { 

     System.out.println(new myInterface(){public String toString(){return "myInterfacetoString";}}); 

     System.out.println(new myInterface(){public String myFunction(){return "myInterfacemyFunction";}}); 
    } 
} 

आउटपुट है ...

myInterfacetoString 
[email protected] 

सभी उत्तरों println में है कि myInterface() बयान गुमनाम वर्ग है कह। लेकिन जैसा कि मैंने इसे पहले ही एक इंटरफ़ेस के रूप में घोषित किया है, यह मुझे उसी नाम के अनाम वर्ग बनाने की अनुमति क्यों देता है ....?

फिर ... अगर इन गुमनाम वर्ग हैं तो वर्ग मुख्य यदि so..I'm संकलन त्रुटि हो रही

+0

क्या यह होमवर्क या जिज्ञासा है? होमवर्क सवालों को टैग करने के लिए इसे अच्छा रूप माना जाता है। – ojrac

+1

सिद्धी, महान सवाल। हालांकि, मेरा सुझाव है कि आप अक्सर नई सामग्री के साथ अक्सर सवाल नहीं बदलते हैं। इसके बजाए, आप एक नया प्रश्न सबमिट कर सकते हैं और इसमें इसका संदर्भ दे सकते हैं। – akf

+0

यह एक खाली इंटरफेस को लागू करने वाले अज्ञात वर्ग का उदाहरण बना रहा है। एक स्ट्रिंग() को ओवरराइड करता है इसलिए System.out.println स्वचालित रूप से इसका उपयोग करेगा। दूसरे में मेरा फ़ंक्शन है, जिसे कॉल नहीं किया जाता है, इसलिए यह ऑब्जेक्ट के टूस्ट्रिंग() का उपयोग करता है जो ऑब्जेक्ट के पते सहित कुछ जानकारी देता है। – mk12

उत्तर

14

जब आप प्रिंट करने की कोशिश मुझे इन गुमनाम classes..But के लिए किसी भी नाम देने के लिए अनुमति चाहिए किसी ऑब्जेक्ट को बाहर करने के लिए, यह toString() विधि को कॉल करेगा। पहले कथन में, आप नई ऑब्जेक्ट बनाते हैं और टूस्ट्रिंग नामक विधि को ओवरराइड भी करते हैं। इसलिए, ऑब्जेक्ट मुद्रित होने पर यह toString() विधि कहा जाता है।

दूसरे कथन में, आप एक ऑब्जेक्ट भी बनाते हैं लेकिन आप ToString() विधि को ओवरराइड नहीं करते हैं ताकि यह ऑब्जेक्ट क्लास की toString() विधि का उपयोग करेगा।

new className(optional argument list){classBody} 

यह अभिव्यक्ति एक अनाम से एक नई वस्तु को दर्शाता है और: Anonymous Classes

यहाँ विवरण की एक प्रति है:

नया प्रश्न के लिए, इस लिंक अपनी समझ के लिए एक अच्छा व्याख्या है पहले अपरिभाषित कक्षा, जो स्वचालित रूप से क्लासनाम नामक कक्षा को बढ़ाती है, और स्पष्ट रूप से किसी इंटरफ़ेस को लागू नहीं कर सकता है। क्लास बॉडी द्वारा नई कक्षा का शरीर दिया जाता है।

इस अभिव्यक्ति को क्रियान्वित करने का परिणाम है कि एक नया वर्ग कि className फैली परिभाषित किया गया है, नया वर्ग के नई वस्तु instantiated जाता है, और अभिव्यक्ति नई वस्तु के लिए एक संदर्भ के द्वारा बदल दिया गया है।

new interfaceName(){classBody} 

यह अभिव्यक्ति एक अनाम और पहले से अपरिभाषित वर्ग, जो स्वत: interfaceName नामित इंटरफ़ेस लागू करता है से एक नई वस्तु को दर्शाता है, और स्वचालित रूप वर्ग वस्तु नामित फैली हुई है। कक्षा स्पष्ट रूप से एक को कार्यान्वित कर सकती है, और केवल एक इंटरफेस, और ऑब्जेक्ट के अलावा किसी भी वर्ग का विस्तार नहीं कर सकता है। एक बार फिर, कक्षा के द्वारा नई कक्षा का शरीर दिया जाता है।

क्या यह आपके लिए अभी स्पष्ट है?

+0

ठीक है ... लेकिन यह toString विधि को कॉल करता है क्योंकि myAbstractClass डिफ़ॉल्ट रूप से ऑब्जेक्ट क्लास को बढ़ाता है ... लेकिन अगर मैं अमूर्त वर्ग के बजाय इंटरफ़ेस का उपयोग करता हूं ... यह मुझे एक ही आउटपुट देता है ... ऐसा क्यों .. .. – Siddhi

+2

सभी ऑब्जेक्ट्स या तो प्रत्यक्ष या अप्रत्यक्ष रूप से, स्पष्ट रूप से या implicity ऑब्जेक्ट क्लास को बढ़ाता है। यदि आप एक अमूर्त वर्ग के बजाय इंटरफेस का उपयोग करते हैं, तो आपके अज्ञात वर्ग अभी भी ऑब्जेक्ट का विस्तार करेंगे। – emory

+0

मैंने इंटरफेस के लिए अज्ञात वर्ग के लिए पहले से ही एक नया, स्पष्ट स्पष्टीकरण जोड़ा है। आपको लिंक को भी देखना चाहिए, यह वास्तव में अच्छा है :) – vodkhang

3

पहले println() पर आप गुमनाम myAbstractClass उदाहरण से toString() विधि अधिभावी कर रहे हैं, इसलिए आप स्ट्रिंग अपने ओवरराइड toString() विधि द्वारा वापस मिलता है, कि println() समारोह के डिफ़ॉल्ट व्यवहार है।

दूसरा println() पर, आप अधिभावी नहीं कर रहे हैं toString() विधि, इसलिए println() डिफ़ॉल्ट (Object से विरासत में मिली) का उपयोग करता है।

एक तरफ ध्यान दें, अपने कोड को सही ढंग से स्वरूपित करने का प्रयास करें, पढ़ने और समझने के लिए बहुत आसान है।

abstract class myAbstractClass{} 

public class Main { 
    public static void main(String[] args) { 
     System.out.println(new myAbstractClass(){ 
      public String toString(){ 
       return "myAbstractClass toString"; 
      } 
     }); 

     System.out.println(new myAbstractClass(){ 
      public String myFunction(){ 
       return "myAbstractClass myFunction"; 
      } 
     }); 
    } 
} 
+0

उत्तर को स्वीकार कर सकते हैं ठीक है ... लेकिन यह toString विधि को कॉल करता है क्योंकि myAbstractClass डिफ़ॉल्ट रूप से ऑब्जेक्ट क्लास को बढ़ाता है ... लेकिन अगर मैं अमूर्त वर्ग के बजाय इंटरफेस का उपयोग करता हूं ... यह मुझे एक ही आउटपुट देता है ... ऐसा क्यों ..? – Siddhi

+1

क्योंकि आपके द्वारा बनाए गए किसी ऑब्जेक्ट इंस्टेंस, भले ही यह एक इंटरफ़ेस को लागू करने वाली कक्षा से है, ऑब्जेक्ट से विस्तारित है। http://java.sun.com/javase/6/docs/api/java/lang/Object.html – Cesar

3

myAbstractClass एक न्यूनतम श्रेणी है। यह वस्तु से विरासत में मिलता है।

कक्षा मुख्य myAbstractClass से दो अनाम आंतरिक कक्षाएं बनाता है, और उनके toString आउटपुट प्रिंट करता है।

  1. आंतरिक वर्ग टूस्ट्रिंग विधि को ओवरराइड करता है और आप इसका आउटपुट देखते हैं।
  2. आंतरिक वर्ग को एक विधि जोड़ा जाता है, और आप डिफ़ॉल्ट टूस्ट्रिंग परिभाषा को डिफ़ॉल्ट करते हैं।
1

दोनों स्थितियों में, आपने ऑब्जेक्ट मुद्रित किया है। तो यह ऑब्जेक्ट की toString() विधि को कॉल करेगा। पहले परिदृश्य में, चूंकि आपने toString() विधि को ओवरराइड कर दिया है, इसलिए यह myAbstractClass toString प्रिंट कर रहा है। दूसरे परिदृश्य में, चूंकि इसे ओवरराइड नहीं किया गया था, इसलिए यह Object कक्षा में कार्यान्वित डिफ़ॉल्ट toString() को कॉल करता है।

मुझे लगता है कि आप दूसरे परिदृश्य में फ़ंक्शन कॉल की अपेक्षा कर रहे हैं जो गलत है। आपने इसे अभी ओवरराइड किया है लेकिन कभी नहीं बुलाया।

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