2010-06-25 9 views
24

मेरे पास एक कक्षा है जो एक कक्षा को बढ़ाती है जिसे मुझे ओवरराइड करने की आवश्यकता है, लेकिन मुझे उस वर्ग की मूल कक्षा को कॉल करने की आवश्यकता है। चूंकि मैं सुपर कॉल नहीं कर सकता क्योंकि यह प्रत्यक्ष माता-पिता को निष्पादित करेगा मेरे माता-पिता वर्ग के माता-पिता को पाने का सबसे अच्छा तरीका क्या है?जावा: आप अभिभावक वर्ग विधि को दो स्तरों तक कैसे पहुंचाते हैं?

मुझे यकीन है कि यह एक मूल प्रश्न है, लेकिन यह थोड़ी देर के बाद से मैं कोई जावा कर रहा हूं।

class A 
{ 
public void myMethod() 
{ /* ... */ } 
} 

class B extends A 
{ 
public void myMethod() 
{ /* Another code */ } 
} 

class C extends B 
{ 
I need to call Class A here 
{ /* Another code */ } 
} 
+1

लगभग हमेशा सुपर का उपयोग कर बुरा रूप है। इसके लिए एकमात्र संभावित अपवाद एक ओवरडिंग विधि कॉल है जो इसे ओवरराइड करता है। ऐसे मामलों में एक सार को लागू करना या कुछ भी विधि नहीं करना बेहतर हो सकता है और "मूल" विधि को अंतिम रूप देने के साथ ओवरराइड किया जा सकता है। हालांकि इसका मतलब है कि आपको केवल एक शॉट मिलता है। गहरी विरासत वैसे भी खराब हैं ... –

+0

[जावा का संभावित डुप्लिकेट] कैसे ग्रैंड माता-पिता की विधि को कॉल करें?] (Http://stackoverflow.com/questions/2584377/java-how-to-call-method-of-grand- माता-पिता)। Http://stackoverflow.com/questions/586363/why-is-super-super-method-not-allowed-in-java – finnw

उत्तर

27

आप नहीं है: यह कैप्सूलीकरण उल्लंघन करती है।

यह कहना ठीक है, "नहीं, मैं अपना व्यवहार नहीं चाहता - मैं अपने माता-पिता के व्यवहार को चाहता हूं" क्योंकि ऐसा माना जाता है कि आप केवल ऐसा ही करेंगे जब यह आपके राज्य को सही तरीके से बनाए रखे।

हालांकि, आप अपने माता-पिता के व्यवहार को बाईपास नहीं कर सकते - जो इसे अपनी स्थिरता को लागू करने से रोक देगा। यदि अभिभावक वर्ग चाहता है ताकि आप दादाजी विधि को सीधे कॉल कर सकें, तो यह एक अलग विधि के माध्यम से इसका खुलासा कर सकता है ... लेकिन यह मूल वर्ग तक है।

+0

धन्यवाद, मैं समझता हूं। मुझे लगता है कि मैं शायद इस गलत तरीके से आ रहा हूं। –

9

आप क्योंकि यह बी द्वारा ओवरराइड किया गया है नहीं कर सकते सी

बात यह है कि आप कक्षा एक की एक विधि कॉल करना चाहते है, लेकिन जहाँ से एक के अंदर का कोई उदाहरण नहीं है उदाहरण? आपने सी को तत्काल किया है, जो कि बी से बी और कुछ विरासत विधियों के साथ एक वर्ग है। यदि बी ए की विधि को ओवरराइड कर रहा है, तो आप इसे सी से एक्सेस नहीं कर सकते हैं, क्योंकि विधि स्वयं सी से संबंधित है (एक विधि नहीं है बी के लिए, यह विरासत में मिला दिया गया है और अब यह सी में है)

संभावित समाधानों:

बी myMethod()

सी ए का एक उदाहरण प्राप्त करता है और एक वर्ग संपत्ति के रूप में सहेजता हावी नहीं होता।

myMethod() एक में स्थिर है और आप A.myMethod() का उपयोग करें (मैं इसकी सलाह नहीं देते)

+0

धन्यवाद, मैं देखता हूं कि मैं इसे गलत कर रहा हूं, लेकिन आपकी व्याख्या के लिए धन्यवाद। यह मुझे समझने में मदद करता है। –

1

इसके अलावा क्या जवाब pakore, आप भी super.myMethod() कॉल श्रृंखला सकता है कि यदि आप के लिए काम करता है। आप बी

class A { 
    public void myMethod() { 
    .... 
    } 
} 

class B extends A { 
    public void myMethod() { 
    .... 
    super.myMethod(); 
    .... 
    } 
} 

class C extends B { 
    public void myMethod() { 
    .... 
    super.myMethod(); //calls B who calls A 
    .... 
    } 
} 

आप अंततः एक से MyMethod कॉल करेंगे में myMethod() से एक से myMethod() फोन करेंगे, लेकिन परोक्ष रूप से ... कि आप के लिए काम करता है।

+0

यह केवल तभी काम करेगा यदि आप बीएमएम विधि() को एमीएम विधि() के समान ही करना चाहते हैं, जो निम्न प्रश्नों की ओर जाता है: आपने इसे पहली बार क्यों ओवरराइड किया? :) – pakore

+0

@pakore: क्षमा करें ... एक उदाहरण के सरल के लिए। जब आप कुछ स्थितियों, झंडे इत्यादि के आधार पर सुपर.मीएम विधि को कॉल करते हैं तो मैंने इसे स्पष्ट कर दिया है उदाहरण के लिए मैंने थोड़ा सा उदाहरण बदल दिया है –

+0

हाँ, मुझे लगता है कि अब आप जो अपडेट कर चुके हैं उसका मतलब है। ध्यान रखें कि आपका समाधान C से AmyMethod() को कॉल करने जैसा नहीं है, क्योंकि, BmyMethod() अन्य चीजें कर रहा है जो शायद सी नहीं चाहते हैं कि वे ऐसा करें। सी सिर्फ एमीएम विधि() चीजें करना चाहता है, न कि और कुछ और। यही कारण है कि मैंने कहा कि केवल काम करता है अगर AmyMethod() === B.myMethod(), और जब यह करता है, ओवरराइडिंग कोई समझ नहीं आता :)। – pakore

0

आप ए की विधि को सीधे कॉल नहीं कर सकते हैं। कुछ मामलों में मैंने इसे मारा है, समाधान को कार्यान्वयन का खुलासा करने के लिए ए में एक विधि जोड़ना था। जैसे

class A 
{ 
    public myMethod() { 
     doAMyMethod(); 
    } 

    void doAMyMethod() { 
     // what A want's on doMyMethod, but now it's available 
     // as a separately identifiable method 
    } 
} 

class C extends B 
{ 
    public void someStuff() { 
     this.doAMyMethod(); 
    } 
} 

योजना कार्यान्वयन (doAMyMethod) से सार्वजनिक इंटरफेस (doMyMethod) अलग करती है। विरासत कार्यान्वयन के विवरण पर निर्भर करता है, और इसलिए यह सख्ती से इतना बुरा नहीं है, लेकिन यदि संभव हो तो मैं इसे टालने का प्रयास करूंगा क्योंकि यह ए और सी

6

में कार्यान्वयन के बीच एक तंग युग्मन बनाता है जो आप पूछ रहे हैं वह खराब है अभ्यास, आप क्या कह रहे हैं कि सी बी नहीं है, लेकिन ए। आपको क्या करने की ज़रूरत है, सी को ए से प्राप्त होता है। फिर आप सुपर को कॉल कर सकते हैं।

नहीं इस एक ही रास्ता है ...

public String A() 
{ 
String s = "hello"; 
return s; 
} 

public String B() 
{ 
String str = super.A(); 
return str; 
} 

public String C() 
{ 
String s = super.B(); 
return s; 
} 
+1

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

0

मैं इस मामले के लिए क्या करना है:

कक्षा सी के अंदर वर्ग एक की वस्तु बनाने और वहाँ क्लास ए एक्सेस करते हैं। इस उदाहरण जो अधिक जानकारी के स्पष्ट किया:

class A{ 
int a; 
} 
class B extends A{ 
int a; 
} 
class C extends B{ 
int a; 
A obj = new A(); 
public void setData(int p,int q, int r) { 

this.a = p; // points to it's own class 
super.a = q;// points to one up level class i.e in this case class B 
obj.a = r; // obj points the class A 
} 
public void getData() { 
    System.out.println("A class a: "+ obj.a); 
    System.out.println("B class a: "+ super.a); 
    System.out.println("C class a: "+this.a); 
} 
} 

public class MultiLevelInheritanceSuper { 

public static void main(String args[]){ 
    C2 obj = new C2(); 
    obj.setData(10, 20, 30); 
    obj.getData(); 

} 

}

इस उदाहरण के उत्पादन में है:

A class a: 30 
B class a: 20 
C class a: 10 
संबंधित मुद्दे