2010-01-28 14 views
5

मैं जावा में नया हूं, और मैंने ओवरराइडिंग विधियों पर कुछ ट्यूटोरियल्स को पढ़ा है, लेकिन एक उदाहरण जो मैं देख रहा हूं वह जिस तरह से मैं उम्मीद कर रहा हूं वह काम नहीं कर रहा है।जावा विधि को ओवरराइड करना

public class A{ 
    public void show(){ 
     System.out.println("A"); 
    } 
    public void run(){ 
     show(); 
    } 
    public static void main(String[] arg) { 
     new A().run(); 
    } 
} 
public class B extends A{ 
    @Override 
    public void show(){ 
     System.out.println("B"); 
    } 
} 

जब मैं का दृष्टांत और B.run फोन(), मैं 'बी' outputted देखने की अपेक्षा करेंगे: उदाहरण के लिए, मैं कोड है। हालांकि, मैं इसके बजाय "ए" देखता हूं। मैं क्या गलत कर रहा हूं?

संपादित करें: हाँ, कक्षाएं दो अलग-अलग फाइलों में हैं। वे संक्षिप्तता के लिए एक साथ दिखाए जाते हैं।

संपादित करें: मुझे यकीन नहीं है कि बी को तत्काल कैसे किया जा रहा है, क्योंकि यह क्लासलोडर का उपयोग करके किसी तृतीय-पक्ष प्रोग्राम द्वारा किया जा रहा है।

संपादित करें: तीसरे पक्ष के कार्यक्रम पर अधिक जानकारी। यह एमेन() को कॉल करके शुरू होता है, जिसे मैंने शुरू में नहीं दिखाया था (माफ करना)। मुझे लगता है कि मुझे "नया ए() रन();" वर्तमान वर्ग के नाम का उपयोग करने के लिए अधिक सामान्य। क्या यह संभव है?

+5

आप कैसे तत्काल और इसे कॉल कर रहे हैं? –

+1

@ प्र्रासून फ़ाइल का केवल कोई उल्लेख नहीं था, केवल कक्षाएं। हम उन वास्तविक फ़ाइलों का अनुमान नहीं लगा सकते थे, जिनमें वे थे। – KLE

उत्तर

6

कि कोड होगा उत्पादन B यदि आप:

(new B()).run(); 

जो भी समस्या है, यह आपके द्वारा उद्धृत कोड में नहीं है।

अपडेट किया गया (आपके संपादन के बाद)

तृतीय-पक्ष प्रोग्राम A.main() बुला रहा है तो इस बात कि खुद A में इंजेक्षन जाएगा (उचित) कुछ भी नहीं आप B में कर सकता है। A.mainnew A().run() कर रहा है, इसमें A का उदाहरण होगा, B का उदाहरण नहीं। उपयोग करने के लिए कोई "वर्तमान वर्ग नाम" नहीं है, या यदि वहां है (आपके दृष्टिकोण पर निर्भर करता है), यह A है, B नहीं है।

आप बल्कि A से किसी तरह से B कॉल करने के लिए, या बस सीधे A संशोधित तृतीय-पक्ष प्रोग्राम (जैसे, B का पूर्णत: नष्ट कर) प्राप्त करने के लिए होगा। आप नहींB का उपयोग करने के लिए A को संशोधित करना चाहते हैं; जो इसे एक वंश के लिए मजबूती से बांधता है और उनके बीच अलगाव को काफी हद तक व्यर्थ बनाता है।

उम्मीद है कि मदद करता है।

+0

यह एक शर्म की बात है कि जावा उस मौजूदा वर्ग का खुलासा नहीं करता है जिसमें कोड रहता है। मैं पाइथन से अधिक परिचित हूं, जहां मैं टाइप (स्वयं) कर सकता हूं या मुख्य रूप से क्लासमेड के रूप में मुख्य() को परिभाषित कर सकता हूं। वैसे भी, मैं बस बी को अपना मुख्य() दे रहा हूं जो बी को तुरंत चालू करता है, और यह समस्या को हल करता है। – Cerin

+0

@ क्रिस: समस्या यह नहीं है कि जावा इसका खुलासा नहीं करता है (यह करता है; एक उदाहरण विधि के भीतर, 'this.getClass()' आपको 'क्लास' उदाहरण देता है जो आपको कक्षा के बारे में जानने के लिए आवश्यक सब कुछ बताता है ; यदि आप कक्षा (स्थैतिक) विधि में हैं, तो आप पहले ही जानते हैं कि आप किस वर्ग में हैं और नाम का उपयोग कर सकते हैं - उदाहरण के लिए, 'ए' - सीधे' कक्षा 'उदाहरण प्राप्त करने के लिए)। यह आपकी समस्या नहीं है। आपकी समस्या यह है कि 'बी' सिर्फ 'एमेन' कहलाते समय आकार या रूप में किसी भी तरह से शामिल नहीं है। 'बी' भी वहां नहीं हो सकता है। यह एक भाषा की बात नहीं है, यह एक चीज है जो आप कोशिश कर रहे हैं। :-) –

+0

@ टीजे। पाउडर: सही, लेकिन केवल जावा में क्योंकि मेरे पास "नया ए()" हार्डकोड करने के अलावा कोई विकल्प नहीं है। पायथन में, मुख्य() एक क्लासमेड हो सकता है, जिसका पहला तर्क स्वचालित रूप से "cls" होगा, इसलिए मैं बस "cls()" कर कक्षा को तुरंत चालू कर सकता हूं। यह विरासत योग्य होगा, इसलिए मुझे बी – Cerin

3

मैंने आपकी दो कक्षाओं को दो फाइलों में डालने की कोशिश की, और यह "बी" आउटपुट करने के लिए अच्छी तरह से काम किया। मैं कहा जाता है:

B b = new B(); 
b.run(); 

UPDATED: के रूप में भी काम करता है (क्योंकि यह एक ही क्रम उदाहरण है):

A a = new B(); 
a.run(); 
+1

'ए = = नया बी() 'ठीक काम करना चाहिए (जब तक कि विधियां स्थैतिक न हों)। – Nate

+0

@ बेडवायर आउटपुट वही है! :-) – KLE

1

यह तत्काल होने पर निर्भर करता है। इसे आज़माएं:

A v1 = new A(); 
A v2 = new B(); 
B v3 = new A(); 
B v4 = new B(); 

v1.run() 
v2.run() 
v3.run() 
v4.run() 
+3

बी v3 = नया ए(); संकलित नहीं होगा, यह असंभव है! – KLE

+0

इसके परिणामस्वरूप लाइन 3 पर संकलन त्रुटि होगी। ए प्रकार बी –

+0

नहीं है हाँ, मुझे पता है, लेकिन यह परिणाम एक उपयोगी अनुभव है। – demas

2

मेरे लिए काम करता है।

package so; 

public class EntryPoint { 

    public static void main(String[] args) { 
     B b = new B(); 
     b.run(); 
    } 
} 

यह 'बी' बाहर प्रिंट:

package so; 

public class A{ 
    public void show(){ 
     System.out.println("A"); 
    } 
    public void run(){ 
     show(); 
    } 
} 

class B extends A{ 
    @Override 
    public void show(){ 
     System.out.println("B"); 
    } 
} 

यहाँ मेरी प्रवेश बिंदु है:

यहाँ एक के लिए मेरे कोड और बी है।

1

मैंने आपके उदाहरण की कोशिश की और मेरा आउटपुट बी था।

आप कैसे तत्काल हैं? यहां चला गया सटीक कोड यहां दिया गया है।

public class Test { 
    public static class A { 
     public void show() { 
      System.out.println("A"); 
     } 

     public void run() { 
      show(); 
     } 
    } 

    public static class B extends A { 
     @Override 
     public void show() { 
      System.out.println("B"); 
     } 
    } 

    public static void main(String args[]) { 
     A a = new B(); 

     a.run(); 
    } 
} 
1

अपने बाहरी कार्यक्रम एक को दर्शाता है, तो आप एक, नहीं बी

होगा लेकिन आप कुछ इस तरह की कोशिश कर सकते हैं, कुछ प्रतिबिंब का उपयोग कर, और "com.mypackage.A" या "कॉम पारित .mypackage.B "आपके प्रोग्राम के लिए तर्क के रूप में।

इस कोड के साथ (अपवाद कैच गायब), आप पारित स्ट्रिंग पैरामीटर के आधार पर "ए" या "बी" प्रिंट करने में सक्षम होंगे।

public static void main(String[] arg) { 
    String className = arg[0]; 
    Class myClass = Class.forName(className); 
    Constructor cons = myClass.getConstructor(new Class[0]); 
    A myObject = (A) cons.newInstance(new Object[0]); 
    myObject.show(); 

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