2013-11-23 11 views
5

मुझे समझ नहीं आता क्यों यह जावा में काम करता है:ऑब्जेक्ट.toString() विभिन्न अंतर्निहित प्रकारों के लिए कैसे काम करता है?

अगर मैं एक वस्तु में एक पूर्णांक वस्तु, उदाहरण है:

Object myIntObj = new Integer(5); 

अब अगर मैं करता हूँ:

System.out.println(myIntObj); 

उत्पादन है: 5

अब मैं इंटीगर क्लास को टॉस्ट्रिंग विधि का एक अंडाकार है लेकिन इस मामले में अलग है (मुझे लगता है)। बहुरूपता के लिए, यदि मेरे पास "पिता परिवर्तनीय" में "बाल वस्तु" है, तो वस्तु अपने असली प्रकार को नहीं बदलती है (इस मामले में इंटीजर) लेकिन ... यह (ऑब्जेक्ट वेरिएबल में) विधि का उपयोग कर सकती है वस्तु वर्ग की, तो क्यों करता है, तो मैं लिखने:

System.out.println(myIntObj); 

मैं सीधे नंबर 5 और नहीं इस वस्तु के संदर्भ देख सकते हैं? क्योंकि डिफ़ॉल्ट रूप से ऑब्जेक्ट क्लास में ToString विधि ऑब्जेक्ट के संदर्भ की केवल एक स्ट्रिंग लौटाती है।

की तरह:

Object currentPlayer = new Player(); 
System.out.println(currentPlayer); 

इस मामले में उत्पादन प्लेयर के संदर्भ है objecet क्योंकि वस्तु वर्ग में toString विधि कहा जाता है।

तो पहले क्यों उदाहरण में मुझे संदर्भ नहीं दिखाई देता है लेकिन सीधे संख्या? तर्क से, बहुरूपता के नियम कहते हैं कि: यदि आपके पास "पिता" चर में "बच्चा" ऑब्जेक्ट है, तो यह ऑब्जेक्ट, अंदर, रीमैनिस करता है लेकिन उसे ऑब्जेक्ट की आबादी की तरह उपयोग किया जाता है, इसलिए वह बस उपयोग कर सकता है क्लास ऑब्जेक्ट और इसलिए ऑब्जेक्ट की विधि, इसलिए वास्तव में अजीब बात है कि मुझे संदर्भ नहीं दिखाई देता है लेकिन सीधे संख्या।

मुझे आशा है कि आप समझेंगे कि मेरा क्या मतलब है।

+0

'प्लेयर 'वर्ग के लिए' toString() 'परिभाषित किया गया है? –

+0

बस एक टिप्पणी। जब आप किसी ऑब्जेक्ट को कंसोल पर आउटपुट करते हैं तो आप जो वर्ण देखते हैं वह हैशकोड के रूप में संदर्भ नहीं है। –

उत्तर

3

आपका अंतिम पैराग्राफ जहां आप अपनी तर्क समझाते हैं, वह थोड़ा गलत है।

तो पहले क्यों उदाहरण में मुझे संदर्भ नहीं दिखाई देता है लेकिन सीधे नंबर? तर्क से, बहुरूपता के नियम कहते हैं कि: यदि आप में "पिता" चर में "बच्चा" ऑब्जेक्ट है, तो इस ऑब्जेक्ट के अंदर, रीमैनिस समान है लेकिन उसे ऑब्जेक्ट की आबादी की तरह उपयोग किया जाता है, इसलिए वह कर सकता है बस क्लास ऑब्जेक्ट का उपयोग करता है और इसलिए ऑब्जेक्ट की विधि, इसलिए वास्तव में अजीब है कि मुझे संदर्भ नहीं दिखाई देता है लेकिन सीधे संख्या।

शुरुआत सही है, लेकिन जिस हिस्से को मैंने बोल्ड किया है वह एक गलत निष्कर्ष है जिसे आपने आकर्षित किया है।

आप सही बहुरूपता के साथ, वस्तु वास्तव में बनी हुई है कि यह है जो कुछ प्रकार के होते हैं, लेकिन संदर्भ प्रकार (चर का प्रकार) को परिभाषित करता है क्या आप इसके साथ कर सकते हैं। हालांकि, संदर्भ प्रकार का वर्णन नहीं करता है कि ऑब्जेक्ट

यह बहुरूपता के पीछे का इरादा है। यह परिभाषित करने के लिए एक अमूर्त है कि यह कैसे काम करता है उससे अलग किया जा सकता है। उदाहरण के लिए, अगर आप इस उदाहरण है:

public class Vehicle { 
    public int getWheelCount() { 
     return 1; 
    } 
} 

public class Car extends Parent { 
    public int getWheelCount() { 
     return 4; 
    } 

    public void blowHorn() { 
     System.out.println("Honk honk!"); 
    } 
} 

public class Bicycle extends Parent { 
    public int getWheelCount() { 
     return 2; 
    } 
} 

Car car = new Car(); 
car.getWheelCount(); // 4 
car.blowHorn(); //"Honk honk!" 

Vehicle v = new Car(); 
v.getWheelCount() // 4 
v.blowHorn(); // COMPILE ERROR HERE! Unknown method 

Bicycle b = new Bicycle(); 
b.getWheelCount(); // 2 

Vehicle v = new Bicycle(); 
v.getWheelCount(); // 2 

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

उदाहरण के लिए इसे बांधने के लिए, सभी Vehicle ऑब्जेक्ट्स में व्हील आकार होता है, इसलिए getWheelCount() हमेशा कॉल करने योग्य होता है चाहे वह वाहन है .getWheelCount() या Car.getWheelCount()। हालांकि, Car.getWheelCount() जो निष्पादित करता है क्योंकि कार इसे अधिक सवारी करती है।

यदि संदर्भ प्रकार Vehicle है, तो आप blowHorn() पर कॉल नहीं कर सकते क्योंकि यह विधि केवल कार पर उपलब्ध है।

वापस अपने उदाहरण के लिए जा रहे, एक पूर्णांक एक पूर्णांक है।

Object i = new Integer(5); 
i.toString(); // 5 

यह प्रिंट 5 क्योंकि मैं एक पूर्णांक हूं। इंटीजर क्लास ओवर-राइड टू स्ट्रिंग। संदर्भ प्रकार (प्रकार आप के रूप में वस्तु की बात कर रहे) केवल जो तरीकों आप कॉल कर सकते हैं, लेकिन नहीं है जो माता पिता/बच्चे वर्ग के संस्करण विधि का कहा जाता है निर्धारित करता है।

+0

बहुत बहुत धन्यवाद! –

+0

आपको बहुत धन्यवाद, मैं 2 साल से प्रोग्रामिंग कर रहा हूं और इस स्थिति में हर बार मैंने एक कास्ट किया क्योंकि मुझे पता था कि जब आप बच्चे को कक्षा में कूदने के लिए बच्चे की कक्षा में बच्चे के ऑब्जेक्ट में बच्चे के ऑब्जेक्ट होते हैं तो विधि को कॉल करने के लिए संभावना होती है। मैंने सोचा कि इस मामले में बाल वर्ग पूरी तरह से भूल गया था, इसलिए हर बार मैंने ((इंटीजर) i) .toString(); –

3

इसे Object के रूप में परिभाषित करके इसका मतलब है कि आपको केवल Object कक्षा में परिभाषित विधियों तक पहुंच होगी।

इसमें toString() शामिल है।

तो जब आप new Player() का दृष्टांत आप अभी भी केवल Object से तरीके उपलब्ध हैं, लेकिन अगर आप इस निर्गम (जैसे Integer.toString() करता है), तब भी आप होगा ओवरराइड instantiated वर्ग में परिभाषित किया।

पुनश्च: पिता -> जनक

+0

मैं गलत जवाब देने वाला था। महान व्याख्या! – Misters

1
Object myIntObj = new Integer(5); 

यहां आप नए Integer उदाहरण बना रहे हैं, न कि एक नंगे Object उदाहरण। तथ्य यह है कि आप इसे Object संदर्भ में निर्दिष्ट कर रहे हैं, यह इसे Object में परिवर्तित नहीं करता है। यह अभी भी Integer है, लेकिन आप इसे Object के रूप में संदर्भित कर सकते हैं क्योंकि यह Object बढ़ाता है। तो जब आप myIntObj.toString() पर कॉल करते हैं, तो आप उस इंस्टेंस की toString() विधि को कॉल कर रहे हैं। यह उदाहरण Integer उदाहरण बन गया है। और इसलिए Integer.toString() कहा जाता है।


Object currentPlayer = new Player(); 

इस मामले में एक ही नियम लागू होते हैं जब currentPlayer.toString() बुला में: आप वास्तव में Player.toString() कॉल कर रहे हैं। यदि Player कक्षा toString() ओवरराइड नहीं करती है, तो पहले आरोही मूल वर्ग toString() कार्यान्वयन कहा जाता है। यदि Player सीधे Object बढ़ाता है, तो Object.toString() कहा जाता है, लेकिन उदाहरण के लिए Player extends Human और Human extends Object, तो Human.toString() को मौजूद होने पर कहा जा रहा है। यदि नहीं, तो Object.toString()

+0

बहुत अच्छी व्याख्या। – Rhys

2

इस प्रकार ओवरराइडिंग विधियों की अवधारणा इस प्रकार काम करती है: एक बार ऑब्जेक्ट पदानुक्रम में किसी ऑब्जेक्ट को कार्यान्वित करने के बाद, यह कार्यान्वयन प्रदान किया जाता है, यह तब तक लागू किया जा रहा है जब तक कि यह किसी अन्य वर्ग द्वारा उत्तराधिकारी पदानुक्रम के नीचे ओवरराइड नहीं हो जाता है।

चूंकि java.lang.IntegertoString() का ओवरराइड प्रदान करता है, तो इस ओवरराइड को java.lang.Object द्वारा प्रदान किए गए कार्यान्वयन के बजाय कहा जाता है।

वहाँ System.out.println(myIntObj) और System.out.println(myIntObj.toString()) बीच कोई अंतर नहीं है, क्योंकि println सभी वस्तुओं जो इसे मुद्रित करने के लिए कैसे पता नहीं है पर आंतरिक रूप से toString फोन होगा।

कारण Player वर्ग अलग-अलग व्यवहार करता है यह है कि यह toString() ओवरराइड नहीं करता है। यदि ऐसा होता है, तो आप इसके परिणाम मुद्रित देखेंगे। हालांकि, ओवरराइड के साथ, java.lang.Object द्वारा प्रदान किया गया डिफ़ॉल्ट कार्यान्वयन कहा जाता है, जो कुछ जेनेरिक ऑब्जेक्ट जानकारी प्रिंट करता है।

0

इस मामले में जहां कर्मचारी एक उपवर्ग प्रबंधक एक विधि getDetails है() अधिरोहित है,

Employee e=new Employee(); 
Employee m=new Manager(); 

पर विचार करें आप e.getDetails() आप व्यवहार कर्मचारी के साथ जुड़े हो जाएगी आह्वान हैं।

यदि आप m.getDetails() का आह्वान करते हैं तो आपको प्रबंधक से जुड़े व्यवहार मिलेंगे।

सामान्य रूप से, आप ऑब्जेक्ट से जुड़े व्यवहार को प्राप्त करते हैं जिस पर चर रनटाइम पर संदर्भित होता है। इस व्यवहार को अक्सर वर्चुअल विधि आमंत्रण के रूप में जाना जाता है।

तो आपका संदर्भ एक वस्तु है जब आप इंटीजर से जुड़े व्यवहार को प्राप्त कर रहे हैं क्योंकि आप रनटाइम पर एक इंटीजर ऑब्जेक्ट का जिक्र कर रहे हैं।

+0

धन्यवाद, लेकिन अगर मैं m.aMethodofManagerClass() ग्रहण करता हूं तो मुझे कहता है "ईह आप नहीं कर सकते !, कर्मचारी में यह विधि मौजूद नहीं है!" यदि आप सही हैं, और मैं संकलन करने की कोशिश करता हूं, तो इसे काम करना होगा! क्योंकि कर्मचारी चर (एम) में रनटाइम पर, मेरे पास manager.aMethodOfManagerClass() है, इसलिए इसे काम करना है, लेकिन नहीं। यह –

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