2013-07-06 9 views
7

वहाँ निम्नलिखित वर्ग हैं:जावा शरीर के साथ विधि "की तरह अमूर्त"

public abstract class Super 
{ 
    public abstract void run(); 
} 

public class Sub1 extends Super 
{ 
    @Override 
    public void run() 
    { 
     System.out.println("Method called"); 
     System.out.println("Sub1 called"); 
    } 
} 

public class Sub2 extends Super 
{ 
    @Override 
    public void run() 
    { 
     System.out.println("Method called"); 
     System.out.println("Sub2 called"); 
    } 
} 

मैं कैसे बच सकते हैं मैं लिखने के लिए है कि "println (" विधि कहा जाता है ");" दो बार?

जवाब

के लिए धन्यवाद CalibeR.50

+1

यदि प्रत्येक कार्यान्वयन समान है, तो आप विधि को सार क्यों देते हैं। – NINCOMPOOP

+0

क्या आप हमें दिखा सकते हैं कि 'रन()' विधि को कैसे कहा जाता है? –

+0

यह सिर्फ एक उदाहरण है, उप 1 और उप 2 में रन विधियों में और कोड होगा। –

उत्तर

12

सुपरक्लूस में सामान्य कार्यक्षमता लाएं, और एक और सार विधि परिभाषित करें, जिसके लिए उप-वर्ग अपने स्वयं के कार्यान्वयन को परिभाषित करेंगे।

public abstract class Super { 
    public void run() { 
     System.out.println("Method called"); 
     printMessage(); 
    } 
    abstract void printMessage(); 
} 

public class Sub1 extends Super { 
    @Override 
    void printMessage() { 
     System.out.println("Sub1 called"); 
    } 
} 

public class Sub2 extends Super { 
    @Override 
    void printMessage() { 
     System.out.println("Sub2 called"); 
    } 
} 

इस तरह आप सुपरक्लास की सामान्य विधि को दो बार कॉल करने के दोहराव से बच सकते हैं।

+0

लेकिन मैं विधि "प्रिंट मैसेज" निजी बनाने में सक्षम नहीं हूं। क्या आपके उदाहरण में केवल "रन" कॉल करने योग्य है? –

+0

@ CalibeR.50 यदि यह निजी है, तो यह सुपरक्लास से उपलब्ध नहीं होगा। हालांकि, आप एक्सेस लेवल संशोधक को छोड़कर इसे * पैकेज निजी * बना सकते हैं, और यह केवल – user000001

+2

पैकेज के भीतर दिखाई देगा, ओह, संरक्षित के बारे में भूल गया। अगर मैं अपने मामले में काम करता हूं तो मैं कोशिश करूंगा। धन्यवाद –

1

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

+0

मैं यह स्पष्ट करने के लिए थोड़ा सा उदाहरण संपादित करूंगा कि मैं –

4

आप अमूर्त वर्ग में रन() कार्यान्वयन रख सकते हैं:

// Super is still an abstract class 
public abstract class Super 
{ 
    // While method run is not an abstract method: 
    public void run() 
    { 
     System.out.println("Method called"); 
    } 
} 

public class Sub1 extends Super 
{ 
    // There's no need of declaring run() here unless you want to change its behaviour 
} 

public class Sub2 extends Super 
{ 
} 

अपने प्रश्न का संपादित संस्करण में, आप बस

// Super is still abstract 
public abstract class Super 
{ 
    // But method run is not abstract 
    public void run() 
    { 
     System.out.println("Method called"); 
    } 
} 

public class Sub1 extends Super 
{ 
    @Override 
    public void run() 
    { 
     super.run(); // <- call Super.run() that prints "Method called" 
     System.out.println("Sub1 called"); 
    } 
} 

public class Sub2 extends Super 
{ 
    @Override 
    public void run() 
    { 
     super.run(); 
     System.out.println("Sub2 called"); 
    } 
} 
+0

करने का प्रयास कर रहा हूं, मैंने यह स्पष्ट करने के लिए अपना प्रश्न संपादित किया कि मैं वास्तव में –

+0

करने का प्रयास कर रहा हूं, आपको सुपर.रुन() को भी कॉल करने की आवश्यकता है यदि आप इसे ओवरराइड करना चुनते हैं उप 1 और उप 2 – veritas

+0

@ CalibeR.50 में विधि मैंने अपना उत्तर –

2

आप रख सकते हैं एक विरासत रन प्राप्ति उपयोग कर सकते हैं सुपर क्लास विधि में सामान्य कोड और इसे उप-वर्ग विधियों से कॉल करें।

public abstract class Super 
{ 
    public abstract void run(); 
    // code common to both the sub classes implemented 
    public void print() { 
    System.out.println("Method called"); 
    } 
} 

public class Sub1 extends Super 
{ 
    @Override 
    public void run() 
    { 
    print(); 
    System.out.println("Sub1 called"); 
    // sub class specific code here 
    } 
} 

public class Sub2 extends Super 
{ 
    @Override 
    public void run() 
    { 
     print(); 
     System.out.println("Sub2 called"); 
     // sub class specific code here 
    } 
} 
+0

जीह, यह काम करेगा। लेकिन क्या यह बल देने की संभावना नहीं है कि कोड "रन" के साथ निष्पादित किया गया है? –

2

"टेम्पलेट विधि पैटर्न" का उपयोग करें:

public class Super 
{ 
    public void template() { 
     System.out.println("Method called"); 
     run(); 
    } 

    public abstract void run(); 
} 

public class Sub1 extends Super 
{ 
    @Override 
    public void run() // out called before run 
    { 

    } 
} 

public class Sub2 extends Super 
{ 
    @Override 
    public void run() // out called before run 
    { 

    } 
} 

Aditionally आप रन संरक्षित कर सकते हैं।

3

यदि run() के कार्यान्वयन का हिस्सा सब 1 और सब 2 दोनों के लिए आम है, तो मेरा सुझाव है कि आप केवल उप-वर्गों में विरासत का उपयोग करें और ओवरराइड करें। यहाँ कोड उदाहरण है:

public abstract class Super 
{ 
    public void run() { 
     // Code shared by all subclasses 
     System.out.println("Method called"); 
    } 

} 

public class Sub1 extends Super 
{ 
    @Override 
    public void run() 
    { 
     super.run(); 
     System.out.println("Sub1 called"); 
    } 
} 

public class Sub2 extends Super 
{ 
    @Override 
    public void run() 
    { 
     super.run(); 
     System.out.println("Sub2 called"); 
    } 
} 

चाल है कि यहाँ Super वर्ग abstract परिभाषित किया जा सकता है, जबकि तरीकों को लागू करने है। यदि आपके पास उप-वर्ग हैं जिन्हें साझा कोड की आवश्यकता नहीं है, तो आप run() को super.run() कोड के बिना ओवरराइड कर सकते हैं और इसे सभी बदल सकते हैं।

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