2012-12-14 22 views
5

मैं कहता हूँ:जब आप ऑब्जेक्ट को तत्काल करते हैं तो आपको दो ऑब्जेक्ट प्रकारों को सूचीबद्ध करने की आवश्यकता क्यों होती है? अगर मैं बिल्ली का एक उपवर्ग (JungleCat <em>फैली</em> कैट) के रूप में JungleCat है, और फिर

JungleCat cat1 = new JungleCat(); 
Cat cat2 = new Cat(); 
Cat cat3 = new JungleCat(); 
JungleCat cat4 = new Cat(); //this one is illegal, right? 
JungleCat cat5; 

मैं सोच रहा हूँ क्या cat1 की वस्तु प्रकार, cat2, cat3, cat4 हैं, और cat5? मैं यह भी सोच रहा हूं कि ऑब्जेक्ट को तुरंत चालू करने में अनावश्यकता क्यों है: जब आप किसी ऑब्जेक्ट को तुरंत चालू करते हैं तो आपको दो ऑब्जेक्ट प्रकारों को सूचीबद्ध करने की आवश्यकता क्यों होती है।

मैं माफी चाहता हूँ अगर यह एक बहुत बुनियादी सवाल है, लेकिन यह बात की तरह है जहाँ मैं सिर्फ एक बार पता करने के लिए चाहते हैं और सभी के लिए और अच्छा तर्क के साथ एक अच्छा जवाब है, जो मैं जानता हूँ कि मैं यहाँ उम्मीद कर सकते हैं के साथ (और नहीं याहू जवाब, आदि): पी

+1

* ऑब्जेक्ट * का प्रकार आवश्यक वैरिएबल के प्रकार के समान नहीं है (या अभिव्यक्ति जिसे अन्यथा उपयोग किया जाता है)। इस पर विचार करें: 'ऑब्जेक्ट str = "हैलो"; '- * ऑब्जेक्ट * का प्रकार' str' को असाइन किया गया है? * अभिव्यक्ति * 'str' का प्रकार क्या है? –

उत्तर

5

नीचे बयान में: -

JungleCat cat1 = new JungleCat(); 

आप इसे दो भागों में टूट सकते हैं: -

JungleCat cat1; // This creates a reference of type `JungleCat` 
cat1 = new JungleCat(); // This creates an object of type `JungleCat`. 

अब, आप cat1 संदर्भ, JungleCat वस्तु को इंगित कर रहे हैं। संदर्भ कुछ भी नहीं हैं जो वस्तु के लिए एक लिंक है, ताकि आप उन्हें एक्सेस कर सकें।

तुम भी सिर्फ इस तरह वस्तु बना सकते हैं: -

new JungleCat(); // Will create an unnamed object 

लेकिन, उपरोक्त मामले में, आप केवल जगह है जहाँ आप instantiated है पर तरीकों और गुण का उपयोग करने में सक्षम हो जाएगा। लेकिन, बाद में, चूंकि आपके पास उस ऑब्जेक्ट तक पहुंचने का कोई संदर्भ नहीं है, इसलिए आप इसके गुणों तक पहुंच नहीं सकते हैं।


अब, चलो 2 बयान के आगे बढ़ते हैं: -

Cat cat = new JungleCat(); 

यहाँ, के रूप में आप अनुमान लगा सकते हैं, तो आप प्रकार Cat - Super Class के संदर्भ, और प्रकार JungleCat का एक उद्देश्य है। यही वह है जिसे हम Polymorphism कहते हैं।

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

यह दूसरी तरफ सही नहीं है। उदाहरण के लिए: -

JungleCat ref = new Cat(); 

अब यह मान्य नहीं है। क्योंकि Cat कोई JungleCat नहीं है। यह कोई और बिल्ली हो सकता है। तो, आपके पास JungleCat संदर्भ बिंदु Cat ऑब्जेक्ट नहीं हो सकता है।


अब यहाँ अपने वास्तविक चिंता का विषय है: -

मैं सोच रहा हूँ क्या कर रहे हैं cat1, cat2, CAT3 cat4, और cat5 की वस्तु प्रकार

खैर , cat1, cat2 .. ऑब्जेक्ट्स नहीं हैं, लेकिन कुछ ऑब्जेक्ट्स को इंगित करने वाले संदर्भ हैं। और आप उपर्युक्त स्पष्टीकरण, उनमें से प्रत्येक के संदर्भ प्रकार से अनुमान लगा सकते हैं।

ऑब्जेक्ट प्रकार ऑब्जेक्ट निर्माण कथन के आरएचएस पर उपयोग किए जाने वाले प्रकार हैं। new कीवर्ड के साथ उपयोग किया जाने वाला प्रकार Object का प्रकार है। आपके पास एक ही ऑब्जेक्ट प्रकार को इंगित करने वाले विभिन्न प्रकार के संदर्भ हो सकते हैं।

तो, आपके पास cat1, और cat2 दोनों एक ही ऑब्जेक्ट प्रकार को इंगित करने वाले संदर्भ हो सकते हैं।

2

जब आप एक वस्तु आप

  1. बारे में बताने की क्या संदर्भ प्रकार या प्रकार (वर्ग) अपने नए चर
  2. की चर्चा करते हुए करने में सक्षम है का दृष्टांत ऑब्जेक्ट को प्रारंभ करने के लिए हमें obje के प्रकार (वर्ग) को निर्दिष्ट करने की आवश्यकता है सीटी

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

Cat cat3 = new JungleCat();

के मामले और केवल JungleCats में (JungleCat, PetCat और सभी बिल्लियों) बिल्ली की ओर इशारा करते के लिए सक्षम है, तो

JungleCat cat3 = new JungleCat();

बारे

object types of cat1, cat2, cat3, cat4, and cat5?

ऑब्जेक्ट प्रकार जो मैं आपको सौंप रहा हूं वह होगा असाइनमेंट ऑपरेटर के दाएं हाथ से टी।

बारे

JungleCat cat4 = new Cat(); //this one is illegal, right?

हाँ, क्योंकि, एक बिल्ली एक JungleCat (केवल एक चीज है कि हम जानते हैं इसके बारे में है कि, यह एक बिल्ली है) होने की जरूरत नहीं है, लेकिन एक JungleCat यकीन है कि के लिए एक बिल्ली है। यही कारण है कि Cat cat= new JungleCat();

+0

धन्यवाद! यहां सभी उत्तरों सहायक थे, लेकिन आपने सब कुछ समझाते हुए एक महान काम किया। – andy

0

JungleCat cat4 = नए कैट (मान्य है); // यह एक अवैध है, है ना?

हां। एक व्युत्पन्न वर्ग संदर्भ इसकी मूल कक्षा को इंगित नहीं कर सकता है।

मुझे आश्चर्य है कि cat1, cat2, cat3, cat4, और cat5 के ऑब्जेक्ट प्रकार क्या हैं?

getClass मेथोस का उपयोग करने के लिए उपयोग करें।

जब आप ऑब्जेक्ट को तुरंत चालू करते हैं तो आपको दो ऑब्जेक्ट प्रकारों को सूचीबद्ध करने की आवश्यकता क्यों होती है।

इसे polymorphism कहा जाता है। यानी एक बेस क्लास संदर्भ इसके किसी भी व्युत्पन्न वर्ग को इंगित कर सकता है।

0

-Polymorphismवस्तु कीउप-वर्ग के रूप में काम वस्तु संदर्भ चर सुपर वर्ग की को सौंपा गया है।

- और यह रूप में एक class polymorphismउप-वर्ग एक ही विरासत पेड़ में होना चाहिए है, और उप-वर्ग सुपर प्रकार का होना चाहिए।

तो

Cat c = new JungleCat(); // Will work 

लेकिन,

JungleCat c = new Cat(); // Won't work 
2

की cat1, cat2, cat3, cat4, और cat5 वस्तु प्रकार क्या हैं?

मुझे नहीं पता कि इस संदर्भ में "ऑब्जेक्ट प्रकार" का क्या अर्थ है। मैं घोषित प्रकार और रन-टाइम प्रकार के संदर्भ में चीजों के बारे में सोचने की बजाय सिफारिश करता हूं।

  • घोषित प्रकार cat1JungleCat है; cat1 का रन-टाइम प्रकार भी JungleCat
  • घोषित प्रकार cat2Cat है; cat2 का रन-टाइम प्रकार भी Cat
  • घोषित प्रकार cat3Cat है; cat3 का रन-टाइम प्रकार JungleCat
  • घोषित प्रकार cat4JungleCat है; cat4 का रन-टाइम प्रकार Cat
    • हां, यह अवैध है। एक स्पष्ट डाउनकास्ट के बिना यह संकलित नहीं होगा; एक स्पष्ट कलाकार के साथ ... यह हो सकता है लेकिन यह रन-टाइम पर अपवाद फेंक देगा।
  • घोषित प्रकार cat5JungleCat है; इसमें कोई रन-टाइम प्रकार नहीं है।

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

उदाहरण के लिए, यदि आप अपने कार्यक्रम के निष्पादन के दौरान एक ही चर करने के लिए एक से अधिक वस्तु आवंटित कर सकते हैं:

Cat c1 = new Cat(); 
c1 = new JungleCat(); 

c1 की घोषित प्रकार निर्धारित करता है क्या तरीकों कि चर के माध्यम से लागू किया जा सकता है:

Cat c1 = new Cat(); 
c1.purr(); // compiles without error 
c1 = new JungleCat(); 
c1.purr(); // compiles without error 

इसी तरह यह निर्धारित करता है कि क्या तरीकों कि चर के माध्यम से लागू नहीं किया जा सकता:

JungleCat jc1 = new JungleCat(); 
Cat c1 = jc1; 
jc1.roar(); // compiles without error - JungleCats can roar! 
c1.roar(); // compile error! Cats don't roar 

यह एक चर के व्यवहार को रन-टाइम प्रकार - पॉलिमॉर्फिज्म द्वारा भिन्न करने की अनुमति देता है - जबकि अभी भी संकलन समय जांच रहा है।

0

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

public static void Claw(Cat cat) 
{ 
    cat.claw(); 
} 

, हम यह मान हमारे कक्षाओं कुछ की तरह हैं:

Cat c = new Cat(); 
Cat j = new JungleCat(); 

पासिंग:

public class Cat 
{ 
    //... 

    public void claw() 
    { 
     System.out.println("Cat claw"); 
    } 
} 

public class JungleCat extends Cat 
{ 
    //... 

    @Override 
    public void claw() 
    { 
     System.out.println("Jungle cat claw"); 
    } 
} 

अब, चलो कुछ वस्तुओं instanstiate जाने हमारे static Claw फ़ंक्शन में:

Claw(c); //Prints "Cat claw" 
Claw(j); //Prints "Jungle cat claw" 
,

public static void Claw(JungleCat junglecat) 
{ 
    junglecat.claw(); 
} 

फिर Claw(c) स्पष्ट रूप से संकलन नहीं होगा, क्योंकि यह एक Cat है:

मान लें हम तो जैसे समारोह को संशोधित किया। Claw(j) के बारे में क्या? यह संकलित नहीं होगा, जैसा कि हमने कहा है कि यह Cat प्रकार भी है। हम जानते हैं कि यह वास्तव में JungleCat है, लेकिन हमने संकलक को बताया है "ठीक है, बस इसका इलाज करें जैसे यह सामान्य Cat प्रकार है"।

इन शुरुआती उदाहरणों में अक्सर क्या खो रहा है क्यों कोई ऐसा करना चाहेगा। बिल्लियों और जानवरों और जैसे अक्सर खराब उदाहरण होते हैं। एक बेहतर उदाहरण के लिए, मान लें कि हमारे पास कुछ कोड है जो विभिन्न ऑपरेटिंग सिस्टम के आधार पर अलग-अलग चीजों को करने के लिए है; चारों ओर एक फाइल ले जाने कहते हैं। यदि यह Linux पर चलता है, तो हम फ़ाइल को /usr/bin पर ले जाना चाहते हैं, अगर यह विंडोज़ पर है, C:\Windows\System32। इसलिए हम तो जैसे एक इंटरफेस को परिभाषित:

public interface FileMover 
{ 
    public void move(File f); 
} 

public class LinuxMover implements FileMover 
{ 
    public void move(File f) 
    { 
     //Move our file to /usr/bin 
    } 
} 

public class WindowsMover implements FileMover 
{ 
    public void move(File f) 
    { 
     //Move our file to C:\Windows\System32 
    } 
} 

अब, हम नहीं जानते कि जो प्रणाली के लिए इस कोड को चलाने के लिए जब तक क्रम जा रहा है - तो हम एक क्रम की जांच उचित वर्ग रनटाइम पर करते हैं और दृष्टांत कर सकते हैं:

वे परवाह नहीं है तरह क्या - - इसलिए हम दो कार्यशील परिभाषाएँ हर बार लिखने के लिए नहीं है हम FileMover, जैसे एक अलग तरह का उपयोग करना चाहते
//Pseudocode 

FileMover fm; 
if(OperatingSystem == LINUX) { 
    fm = new LinuxMover(); 
} 
else if(OperatingSystem == WINDOWS) { 
    fm = new WindowsMover(); 
} 

fm.move(); 

इसी तरह, किसी भी काम करता है बस एक FileMover ले जा सकते हैं doSomething(WindowsFileMover m) और doSomething(LinuxFileMover m), हम बस प्रतिलिपि बना सकते हैं यह एक समारोह doSomething(FileMover m) के साथ, सही प्रकार में पास करें, और यह "बस काम करेगा"।

यह संभवतः प्रश्न की आवश्यकता के मुकाबले बहुत अधिक जानकारी है, लेकिन उम्मीद है कि यह आपको कुछ अंतर्ज्ञान भी देता है कि सामान्य बिल्लियों और कुत्तों की तुलना में कुछ और ठोस तरीके से ऐसी चीजें क्यों की जाती हैं।

+0

"यह बहुरूपता के पीछे मौलिक सिद्धांत है।" आप स्थिर टाइपिंग या परिवर्तनीय घोषणाओं के बिना बहुरूपता प्राप्त कर सकते हैं। –

+1

@RichardJPLeGuen सच है, आप कर सकते हैं। शायद मुझे वहाँ ब्रैकेट रखना चाहिए था, "यह बहुरूपता (जावा में) के पीछे मौलिक सिद्धांत है"। – Yuushi

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

  • कोई संबंधित समस्या नहीं^_^