2013-03-20 8 views
5

यहाँ तीन वर्गों कि मैंने लिखा हैं:बहुरूपता

public class Shape { 

    public int x = 0; 

    public void getArea() { 
     System.out.println("I don't know my area!"); 
    } 

    public String toString() { 
     return "I am a shape!"; 
    } 

    public int getX() { 
     return x; 
    } 
} 

public class Rectangle extends Shape { 

    public int x = 1; 

    public int getX() { 
     return x; 
    } 

    public void getArea() { 
     System.out.println("L*W"); 
    } 

    public String toString() { 
     return "I am a rectangle!"; 
    } 
} 

public class Tester { 

    public static void main(String[] args) { 
     Shape s = new Shape(); 
     Rectangle r = new Rectangle(); 

     System.out.println(r); 
     System.out.println(r.x + "\n"); 

     s = r; 
     System.out.println(s); 
     s.getArea(); 
     System.out.println(s.x); 
     System.out.println(s.getX()); 
    } 
} 

परीक्षक वर्ग के मुख्य विधि से उत्पादन होता है:

 
I am a rectangle! 

1 

I am a rectangle! 

L*W 

0 

1 

s.x लौट क्यों करता है 0 और नहीं 1? जैसा कि एक आयत परिवर्तक का वर्तमान उदाहरण नहीं है और उस वर्ग में भी वही इंस्टेंस वैरिएबल घोषित किया गया है, या आयताकार वर्ग में परिवर्तनीय आकार वर्ग में पिछले सार्वजनिक एक्स चर को ओवरराइड नहीं करता है क्योंकि यह getX() इस प्रकार आयताकार वर्ग में विधि 1 लौट रही है?

एक सामान्य नियम के रूप में सुपरक्लास के पास इसके उप-वर्ग विधियों के कार्यान्वयन तक पहुंच केवल तभी होती है जब उन्हें उस कक्षा में भी घोषित किया जाता है? ऐसा इसलिए है क्योंकि संकलक देखेंगे कि एक ही हस्ताक्षर के साथ समान मात्रा में "आकार" वर्ग (ओवरराइड आयताकार कार्यान्वयन के साथ) में हैं और उन्हें वैध आकार विधियों के रूप में स्वीकार करते हैं?

अग्रिम धन्यवाद,

+0

में उदाहरण चर छिपने के बारे में अधिक पढ़ सकते हैं क्यों अपने उदाहरण चर सार्वजनिक है !!? आपको कभी भी एक इंस्टेंस वैरिएबल सार्वजनिक नहीं करना चाहिए !!! – DrinkJavaCodeJava

+0

यह देखने के लिए एक परीक्षण था कि क्या होगा। मैं encapsulation के बारे में अच्छी तरह से अवगत हूँ क्योंकि मैंने पहले एक एमवीसी डिजाइन किया है। – PragmaticProgrammer

उत्तर

13

जावा में फ़ील्ड के लिए कोई बहुलकता नहीं है। हालांकि, विरासत है। आपने जो प्रभावी ढंग से किया है वह उसी आय के साथ आपके आयत वर्ग में दो फ़ील्ड बना रहा है। क्षेत्र के नाम को प्रभावी ढंग से कर रहे हैं:

public class Rectangle { 
    public int Shape.x; 
    public int Rectangle.x; 
} 

ऊपर वैध जावा, इसकी कितना क्षेत्रों के संपूर्ण दायरे के भीतर अपनी कक्षा

में scoped रहे हैं का एक उदाहरण का प्रतिनिधित्व नहीं करता आयत वर्ग, एक ही नाम के सुपरक्लास क्षेत्र छिपा है। इसलिए जब भी आप कक्षा के भीतर x, या स्कोप्ड नाम this.x का संदर्भ देते हैं, तो आप Rectangle में परिभाषित फ़ील्ड का जिक्र कर रहे हैं। आप वास्तव में सुपरक्लास फ़ील्ड तक पहुंच सकते हैं, स्कोप्ड नाम super.x के साथ।

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

Shape s = new Shape(); 
Rectangle r = new Rectangle(); 

s = r; 
System.out.println(s.x); 

उत्पादन 0 है क्योंकि s का संकलन समय प्रकार Shape (नहीं Rectangle) है। जब आप ऐसा करते हैं तो आप इस व्यवहार में बदलाव देख सकते हैं:

Shape s = new Shape(); 
Rectangle r = new Rectangle(); 

s = r; 
System.out.println(((Rectangle)s).x); 

प्रेस्टो! आपका आउटपुट अब 1 है, क्योंकि संकलक देखता है कि आपने Rectangle पर फ़ील्ड पहुंच को स्कॉप्ड किया है।

दृश्यता के नियमों गाढ़ा करने के लिए:

आप JLS, Section 8.3.3.2

+0

अब धन्यवाद मैं समझता हूँ! तो क्या ssgetArea() का उपयोग करते समय मैंने कहा कि विधियों आयताकार कार्यान्वयन का उपयोग करते हैं? मुझे पता है कि वे दिखाई देते हैं लेकिन संकलन समय पर वास्तव में क्या हो रहा है? धन्यवाद – PragmaticProgrammer

+0

@ प्रागमैटिकप्रोग्रामर - विधियों के नियम अलग-अलग हैं, एक बात के लिए, वे वास्तव में अतिरंजित हो सकते हैं। याद रखें कि मैंने छुपा चर के लिए कैसे उल्लेख किया है, संकलन समय पर संकल्प किया जाता है? अच्छी तरह से ओवरराइड तरीकों के लिए, रनटाइम पर संकल्प किया जाता है। तो, यदि आपने 'आकार एस = नया आयत() किया था; s.getArea(); 'विधि विधि' आयताकार 'के लिए है, और superclass 'आकार' के लिए नहीं है। – Perception

0

उपवर्गों केवल, सुपर क्लास में चर और तरीकों के वारिस के आसपास नहीं अन्य तरीके से। तो x को बराबर 1 प्राप्त करने के लिए आपको आयताकार को आकार नहीं देना है। जब तक आप अन्य व्यक्ति को कास्टिंग के साथ प्रदर्शित नहीं करते हैं, तो आपको वास्तविक प्रोग्रामिंग में जितना संभव हो उतना टालना चाहिए। इसके अलावा आपको कभी भी सार्वजनिक आवृत्ति चर का उपयोग नहीं करना चाहिए! यदि आप चर बनना चाहते हैं तो कम से कम उन्हें स्थिर या स्थिर बना दें।

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