बहुरूपता बनाम ओवरलोडिंग बनाम बहुरूपता


347

जावा के संदर्भ में, जब कोई पूछता है:

बहुरूपता क्या है?

क्या ओवरलोडिंग या ओवरराइडिंग एक स्वीकार्य जवाब होगा?

मुझे लगता है कि इससे कुछ अधिक है।

यदि आपके पास एक सार आधार वर्ग है जो बिना किसी कार्यान्वयन के एक विधि को परिभाषित करता है, और आपने उप-वर्ग में उस पद्धति को परिभाषित किया है, तो क्या यह अभी भी अधिरोहित है?

मुझे लगता है कि ओवरलोडिंग सुनिश्चित करने के लिए सही जवाब नहीं है।


नीचे दिए गए उत्तर बहुरूपता के बारे में बहुत अच्छी तरह से बताते हैं। लेकिन मुझे यह कहने में कड़ी आपत्ति है कि ओवरलोडिंग एक प्रकार का बहुरूपता है, जिसे मैंने अपने प्रश्न और उत्तर में उचित ठहराने की कोशिश की कि वास्तव में ओवरलोडिंग पर ध्यान केंद्रित करना बहुरूपता है या नहीं। मैंने @ थ्रेड में मौजूद डिजिटल गैबेज उत्तर को सही ठहराने की कोशिश की। संदर्भ विस्तार: विधि अधिभार एक स्थिर / संकलन-समय बंधन है, लेकिन बहुरूपता नहीं है। क्या बहुरूपता के साथ स्थैतिक बंधन को सहसंबंधित करना सही है?
प्रवीणकुमार लालसंगी 20

जवाबों:


894

बहुरूपता को व्यक्त करने का सबसे स्पष्ट तरीका एक सार आधार वर्ग (या इंटरफ़ेस) है

public abstract class Human{
   ...
   public abstract void goPee();
}

यह वर्ग अमूर्त है क्योंकि goPee()विधि मनुष्य के लिए निश्चित नहीं है। यह केवल उपवर्ग पुरुष और महिला के लिए निश्चित है। इसके अलावा, मानव एक अमूर्त अवधारणा है - आप एक ऐसा मानव नहीं बना सकते जो न तो नर हो और न ही मादा। यह एक या एक हो गया है।

इसलिए हम अमूर्त वर्ग का उपयोग करके कार्यान्वयन को स्थगित करते हैं।

public class Male extends Human{
...
    @Override
    public void goPee(){
        System.out.println("Stand Up");
    }
}

तथा

public class Female extends Human{
...
    @Override
    public void goPee(){
        System.out.println("Sit Down");
    }
}

अब हम पेशाब जाने के लिए इंसानों से भरा एक पूरा कमरा बता सकते हैं।

public static void main(String[] args){
    ArrayList<Human> group = new ArrayList<Human>();
    group.add(new Male());
    group.add(new Female());
    // ... add more...

    // tell the class to take a pee break
    for (Human person : group) person.goPee();
}

इसे चलाने से उपज होगी:

Stand Up
Sit Down
...

37
@yuudachi। एक कक्षा को पढ़ाते समय मैं इस उदाहरण के साथ आया था। विहित "बैंक खाता" वर्ग वास्तव में आधार वर्ग की "अमूर्तता" को व्यक्त नहीं करता था। अन्य विहित उदाहरण (पशु, शोर करें) समझने के लिए बहुत सार था। मैं बहुत स्पष्ट उपवर्गों के साथ एकल आधार की तलाश में था। वास्तव में, goPee () एकमात्र उदाहरण था जिसके साथ मैं आया था वह सेक्सिस्ट या रूढ़िवादी नहीं था। (यद्यपि कक्षा में, मैंने स्टैंड अप या बैठने के बजाय "बाईं ओर हॉल नीचे" मुद्रित किया।)
क्रिस कूडमोर

100
यह उदाहरण जैविक प्रणालियों का वर्णन करने के लिए एक पदानुक्रमित प्रणाली का उपयोग करने की कठिनाई पर भी प्रकाश डालता है। कुछ मनुष्य, जैसे बहुत युवा, लगभग किसी भी स्थिति में पेशाब करते हैं - और शिशुओं को आसानी से goPee () नहीं बताया जा सकता है। कुछ मनुष्य इंटरसेक्स हैं, जहां "पुरुष" या "मादा" के जैविक लेबल बल्कि बीमार परिभाषित हो जाते हैं; सामाजिक अर्थ और भी जटिल हैं। एक शिक्षण उदाहरण के रूप में, यह दिखाता है कि मॉडलिंग की धारणाओं के नकारात्मक परिणाम कैसे हो सकते हैं, जैसे कि यह निहितार्थ कि कोई (जैसे, ओओ प्रोग्रामिंग का छात्र) जो असंयम या प्रतिच्छेदन है वह वास्तव में मानव नहीं है।
एंड्रयू डल्के

7
मैं कम से कम एक मुट्ठी भर मनुष्यों के बारे में सोच सकता हूं जो आपके "को नापसंद करते हैं" आप एक ऐसा मानव नहीं बना सकते जो न तो पुरुष है और न ही महिला "थीसिस, हालांकि यह अभी भी आपके कोड का सच होगा ... बुरा अमूर्त मुझे लगता है कि मैं कह रहा हूं ? ;)
फ्रैंक डब्ल्यू। ज़मेट्टी

2
मुझे लगता है कि यह बताना महत्वपूर्ण है कि यह केवल बहुरूपता है क्योंकि कॉल करने के लिए goPee () से कौन सा संस्करण केवल रनटाइम के लिए निर्धारित किया जा सकता है। हालांकि इस उदाहरण का अर्थ है कि, यह बताना अच्छा है कि वास्तव में यह बहुरूपता क्यों है। इसके अलावा, इसे सहोदर वर्गों की आवश्यकता नहीं है। यह एक अभिभावक-बच्चे का रिश्ता भी हो सकता है। या यहां तक ​​कि पूरी तरह से असंबंधित वर्ग जो संयोग से एक ही कार्य करते हैं। इसका एक उदाहरण .toString () फ़ंक्शन हो सकता है। जिसे किसी भी वस्तु पर बेतरतीब ढंग से कहा जा सकता है, लेकिन संकलक कभी भी नहीं जान सकता कि किस प्रकार की वस्तु है।
Tor Valamo

20
@AndrewDalke, जैविक जटिलता पर नोट्स के लिए +1। इसके अलावा, goPeeएक इनपुट के रूप में गुरुत्वाकर्षण क्षेत्र नहीं लेता है। वैश्विक स्थिति पर यह निर्भरता इकाई-परीक्षण को CatheterizedIntersexAstronautकठिन बनाती है, और यह दर्शाती है कि गुण की संरचना के लिए उपवर्ग हमेशा सर्वोत्तम विधि नहीं हो सकती है।
माइक सैमुअल

99

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

एक ओवरराइडएक प्रकार का कार्य है जो एक वर्ग में होता है जो दूसरे वर्ग से विरासत में मिलता है। एक ओवरराइड फ़ंक्शन, बेस क्लास से विरासत में मिली एक फ़ंक्शन को "रिप्लेस" करता है, लेकिन इस तरह से करता है कि इसे तब भी कहा जाता है जब इसके वर्ग का एक उदाहरण बहुरूपता के माध्यम से एक अलग प्रकार का नाटक कर रहा हो। पिछले उदाहरण का जिक्र करते हुए, आप अपनी खुद की कक्षा को परिभाषित कर सकते हैं और स्ट्रींग () फ़ंक्शन को ओवरराइड कर सकते हैं। क्योंकि यह फ़ंक्शन ऑब्जेक्ट से विरासत में मिला है, यह तब भी उपलब्ध होगा जब आप इस वर्ग के उदाहरण को ऑब्जेक्ट-प्रकार चर में कॉपी करते हैं। आम तौर पर, यदि आप एक वस्तु होने का दिखावा करते हुए अपनी कक्षा में स्टर्लिंग () को कॉल करते हैं, तो स्ट्रींग का संस्करण जो वास्तव में आग होगा वह ऑब्जेक्ट पर ही परिभाषित है। हालाँकि, क्योंकि फ़ंक्शन एक ओवरराइड है, आपकी कक्षा से स्ट्रैस्ट्रिंग () की परिभाषा का उपयोग तब भी किया जाता है जब क्लास उदाहरण '

ओवरलोडिंग एक ही नाम के साथ कई तरीकों को परिभाषित करने की क्रिया है, लेकिन विभिन्न मापदंडों के साथ। यह या तो अधिभावी या बहुरूपता से संबंधित नहीं है।


8
यह पुराना है, लेकिन बहुरूपता का अर्थ यह नहीं है कि वंशानुक्रम में दूसरे वर्ग का होना जरूरी है। यह जावा में करता है यदि आप इंटरफेस को वंशानुक्रम के पेड़ का हिस्सा मानते हैं, लेकिन गो में नहीं, जहां इंटरफेस को अंतर्निहित रूप से लागू किया जाता है।
जेएन

5
वास्तव में, आपको बहुरूपता के लिए कक्षाओं की आवश्यकता नहीं है।
StCredZero

3
मैं एक नौसिखिया हूं, और अगर मैं गलत हूं तो मुझे सही करें, लेकिन मैं यह नहीं कहूंगा कि ओवरलोडिंग बहुरूपता से संबंधित नहीं है। कम से कम जावा में, बहुरूपता वह है जब कार्यान्वयन को कॉलर के प्रकार के आधार पर चुना जाता है, और ओवरलोडिंग तब होता है जब कार्यान्वयन को मापदंडों के प्रकार के आधार पर चुना जाता है, है न? दोनों के बीच समानता देखकर मुझे इसे समझने में मदद मिलती है।
csjacobs24

9
गलत। Ad hoc polymorphismआपके ओवरलोडिंग अनुभाग में आपने जो वर्णन किया है और वह बहुरूपता का मामला है।
जॉसी काल्डेरन

1
"यह या तो अधिभावी या बहुरूपता से संबंधित नहीं है"। यह कथन गलत है।
शैलेश प्रतापवार

45

बहुरूपता का अर्थ है एक से अधिक रूप, एक ही वस्तु का आवश्यकता के अनुसार अलग-अलग संचालन करना।

बहुरूपता दो तरीकों का उपयोग करके प्राप्त किया जा सकता है, वे हैं

  1. ओवरराइड करने की विधि
  2. विधि अधिभार

विधि अधिभार अर्थ है एक ही विधि नाम का उपयोग करके एक ही कक्षा में दो या दो से अधिक विधियाँ लिखना, लेकिन पासिंग पैरामीटर अलग हैं।

ओवरराइड करने की विधि मतलब है कि हम अलग-अलग कक्षाओं में विधि के नाम का उपयोग करते हैं, इसका मतलब है कि बच्चे की कक्षा में पैरेंट क्लास विधि का उपयोग किया जाता है।

जावा में बहुरूपता प्राप्त करने के लिए एक सुपर क्लास रेफरेंस वेरिएबल सब क्लास ऑब्जेक्ट को पकड़ सकता है।

बहुरूपता को प्राप्त करने के लिए प्रत्येक डेवलपर को परियोजना में समान विधि नामों का उपयोग करना चाहिए।


4
अच्छा जवाब के लिए +1। स्वीकृत उत्तर केवल एक प्रकार के बहुरूपता की व्याख्या करता है। यह उत्तर पूर्ण है।
अपादान

1
बहुरूपता एक प्रतिमान (OOP) है, लेकिन ओवरराइडिंग और ओवरलोडिंग भाषा सुविधाएं हैं।

बहुरूपता को सामान्य प्रकार से भी प्राप्त किया जा सकता है।
मिन्ह नघ।

43

यहाँ छद्म सी # / जावा में बहुरूपता का एक उदाहरण दिया गया है:

class Animal
{
    abstract string MakeNoise ();
}

class Cat : Animal {
    string MakeNoise () {
        return "Meow";
    }
}

class Dog : Animal {
    string MakeNoise () {
        return "Bark";
    }
}

Main () {
   Animal animal = Zoo.GetAnimal ();
   Console.WriteLine (animal.MakeNoise ());
}

मुख्य कार्य जानवर के प्रकार को नहीं जानता है और मेकनोइस () पद्धति के एक विशेष कार्यान्वयन के व्यवहार पर निर्भर करता है।

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


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

आकार -> समांतर
चतुर्भुज

@ yankee2905 इस मामले में, मुझे लगता है कि आप इंटरफेस का उपयोग कर सकते हैं, क्योंकि एक वर्ग कई इंटरफेस को लागू कर सकता है।
सैम ००३

1
@ शीशेंग या अमूर्त अभिभावक वर्ग में पेशाब करने की विधि जोड़ना? मैं इंटरफ़ेस का उपयोग कुछ और को लागू करने के लिए करूंगा।
जॉय रोहन

42

ओवरराइडिंग और ओवरलोडिंग दोनों का उपयोग बहुरूपता को प्राप्त करने के लिए किया जाता है।

आपके पास एक वर्ग में एक विधि हो सकती है जो एक या अधिक उपवर्गों में ओवरराइड होती है । विधि अलग-अलग चीजों को करती है जिसके आधार पर किसी वस्तु को पलटने के लिए किस वर्ग का उपयोग किया गया था।

    abstract class Beverage {
       boolean isAcceptableTemperature();
    }

    class Coffee extends Beverage {
       boolean isAcceptableTemperature() { 
           return temperature > 70;
       }
    }

    class Wine extends Beverage {
       boolean isAcceptableTemperature() { 
           return temperature < 10;
       }
    }

आपके पास एक ऐसी विधि भी हो सकती है जो दो या अधिक तर्कों के साथ अतिभारित हो। विधि विभिन्न प्रकार के तर्कों (नों) के आधार पर पारित करती है।

    class Server {
        public void pour (Coffee liquid) {
            new Cup().fillToTopWith(liquid);
        }

        public void pour (Wine liquid) {
            new WineGlass().fillHalfwayWith(liquid);
        }

        public void pour (Lemonade liquid, boolean ice) {
            Glass glass = new Glass();
            if (ice) {
                glass.fillToTopWith(new Ice());
            }
            glass.fillToTopWith(liquid);
        }
    }

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

7
जैसा कि मैंने यहां अपने जवाब में कहा है, मैं असहमत हूं - दो विशेषताएं रूढ़िवादी नहीं हैं, लेकिन निकटता से संबंधित हैं। बहुरूपता! = वंशानुक्रम। आप मेरे अप वोट हैं।
पीटर मेयर

2
दूसरे शब्दों में, बहुरूपता बनाम तदर्थ बहुरूपता टाइप करें। मैं इस जवाब को बढ़ा-चढ़ाकर बता रहा हूं, भले ही यह जितना हो सके पूरा न हो, क्योंकि यह सही ढंग से बताता है कि ओवरलोडिंग और ओवरराइडिंग दोनों ही बहुरूपता से संबंधित हैं। यह कहना कि ओओपी भाषाओं में बहुरूपता केवल वर्ग विरासत द्वारा प्राप्त की जा सकती है, बस गलत है - हमें यह याद रखना चाहिए कि जावा और सी ++ के अलावा कुछ अन्य ओओपी भाषाएं भी हैं, जहां व्यक्ति कई प्रेषण, तदर्थ हाइपरोफिज्म, पैरामीट्रिक बहुरूपता और इसी तरह की अवधारणाओं का उपयोग कर सकता है। ।
रासेन

2
@ कृष्णा यह अधूरा हो सकता है, लेकिन यह बाकी आईएमएचओ की तुलना में सवाल का बेहतर जवाब देता है। इसके अलावा, बहुत अच्छा है कि आपने तदर्थ और पैरामीट्रिक बहुरूपता का उल्लेख किया।
वैलेंटाइन रादु

15

आप सही हैं कि ओवरलोडिंग का जवाब नहीं है।

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


3
यह उस वस्तु का व्यवहार नहीं होना चाहिए जो बदलता है, लेकिन उसका कार्यान्वयन। समान व्यवहार, अलग कार्यान्वयन, यह बहुरूपता है।
QBziZ

@QBziZ आप परिभाषित करने की जरूरत व्यवहार , विशेष रूप से विशेषण ही । यदि व्यवहार समान है, तो उनका कार्यान्वयन अलग क्यों होना चाहिए? ऐसा नहीं है कि कोई एक निश्चित कार्यान्वयन से नाखुश है, इसलिए एक अलग की आवश्यकता है।
SAN16ошƒаӽ

11

विशेष रूप से कहते हैं कि ओवरलोडिंग या ओवरराइडिंग पूरी तस्वीर नहीं देती है। बहुरूपता किसी वस्तु की अपने प्रकार के आधार पर व्यवहार करने की क्षमता है।

मैं यहाँ कुछ उत्तरों से असहमत हूँ कि ओवरलोडिंग इस मामले में बहुरूपता (पैरामीट्रिक पॉलीमॉर्फिज़्म) का एक रूप है जिसमें एक ही नाम वाला एक तरीका अलग-अलग पैरामीटर प्रकार दे सकता है। एक अच्छा उदाहरण ऑपरेटर ओवरलोडिंग है। आप "+" को विभिन्न प्रकार के मापदंडों को स्वीकार करने के लिए परिभाषित कर सकते हैं - जैसे तार या अंतर - और उन प्रकारों के आधार पर, "+" अलग तरह से व्यवहार करेंगे।

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


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

अकेले विरासत के संदर्भ में बहुरूपता को समझाना आसान हो सकता है, लेकिन जिस तरह से यह विशेष प्रश्न पूछा गया था, मुझे लगता है कि यह पैरामीट्रिक बहुरूपता का भी वर्णन करने के लिए विवेकपूर्ण है।
पैट्रिक McElhaney

4
स्पष्ट होने के लिए, मुझे लगता है कि विभिन्न रूपों को कहा जाना चाहिए - जो मैंने पर्याप्त रूप से नहीं किया है - क्योंकि यहां कुछ उत्तर दिए गए हैं जो पूर्ण रूप से प्रस्तुत किए गए हैं। मैं सम्मानपूर्वक इस बात से असहमत हूं कि "प्रोग्रामर के संदर्भ में ... 'बहुरूपता' का अर्थ हमेशा 'वंशानुक्रम आधारित बहुरूपता' होता है"
पीटर मेयर

2
मुझे लगता है कि Ad-hoc_polymorphism en.wikipedia.org/wiki/… के
मनु

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

7

बहुरूपता का अर्थ है "कई रूप"।

यह प्राप्त करने के लिए विरासत की आवश्यकता नहीं है ... इंटरफ़ेस कार्यान्वयन के रूप में, जो विरासत में बिल्कुल नहीं है, बहुरूपताओं की जरूरतों को पूरा करता है। तर्क के अनुसार, अंतरायन कार्यान्वयन, बहुरूपता की अपेक्षा "बहुरंगी" जरूरतों को पूरा करता है।

उदाहरण के लिए, क्या आप उन सभी चीजों का वर्णन करने के लिए एक सुपर-क्लास बनाएंगे जो उड़ सकती हैं? मुझे नहीं सोचना चाहिए। आपको एक इंटरफ़ेस बनाने के लिए सबसे अच्छा काम किया जाएगा जो उड़ान का वर्णन करता है और उस पर छोड़ देता है।

इसलिए, चूंकि इंटरफेस व्यवहार का वर्णन करता है, और विधि के नाम व्यवहार का वर्णन करते हैं (प्रोग्रामर के लिए), यह बहुत ज्यादा दूर नहीं है कि विधि को ओवरलोडिंग के रूप में पॉलीमोर्फिज़्म के रूप में माना जाए।


2
निश्चित रूप से सबसे अच्छा जवाब अभी तक। बहुरूपता को सभी भाषा निर्माणों पर लागू किया जा सकता है, यह संज्ञाएं (कक्षाएं) या क्रियाएं (विधियां) हो सकती हैं।
राडू गैसलर

6

क्लासिक उदाहरण, कुत्ते और बिल्लियाँ जानवर हैं, जानवरों के पास मेकओनिज़ विधि है। मैं उन जानवरों की एक सरणी के माध्यम से पुनरावृति कर सकता हूं, जो उन पर मेकओनिज़ कहते हैं और उम्मीद करते हैं कि वे संबंधित कार्यान्वयन करेंगे।

कॉलिंग कोड को यह जानने की जरूरत नहीं है कि वे कौन से विशिष्ट जानवर हैं।

मुझे लगता है कि मैं बहुरूपता के रूप में क्या सोचता हूं।


4

बहुरूपता एक वस्तु के कई रूपों में प्रकट होने की क्षमता है। इसमें उन वस्तुओं के परिवार के निर्माण के लिए विरासत और आभासी कार्यों का उपयोग करना शामिल है जिन्हें आपस में जोड़ा जा सकता है। बेस क्लास में वर्चुअल फ़ंक्शंस के प्रोटोटाइप शामिल होते हैं, जो संभवतः डिमाइंडलीट या डिफॉल्ट इम्प्लीमेंटेशन के साथ होता है क्योंकि एप्लिकेशन डिक्टेट होता है, और विभिन्न व्युत्पन्न क्लासेस प्रत्येक को अलग-अलग व्यवहार को प्रभावित करने के लिए अलग-अलग लागू करते हैं।


4

न तो:

ओवरलोडिंग तब होती है जब आपके पास समान फ़ंक्शन नाम होता है जो विभिन्न मापदंडों को लेता है।

ओवरराइडिंग तब होता है जब एक बच्चा वर्ग अपने स्वयं के माता-पिता की विधि को अपने स्वयं के स्थान पर बदल देता है (यह अपने आप में बहुरूपता का गठन नहीं करता है)।

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

जावा में आप संग्रह पुस्तकालय के साथ बहुरूपता को बहुत देखते हैं:

int countStuff(List stuff) {
  return stuff.size();
}

सूची आधार वर्ग है, जब तक आप एक सूची की तरह काम करते हैं, तब तक संकलक के पास कोई सुराग नहीं होता है, जब आप किसी लिंक की गई सूची, वेक्टर, सरणी, या एक कस्टम सूची कार्यान्वयन की गिनती करते हैं:

List myStuff = new MyTotallyAwesomeList();
int result = countStuff(myStuff);

यदि आप ओवरलोडिंग कर रहे थे तो आपके पास होगा:

int countStuff(LinkedList stuff) {...}
int countStuff(ArrayList stuff) {...}
int countStuff(MyTotallyAwesomeList stuff) {...}
etc...

और countStuff () के सही संस्करण को कंपाइलर द्वारा मापदंडों से मिलान करने के लिए चुना जाएगा।


4

हालाँकि, इस पोस्ट में पहले से ही Polymorphism को बहुत अच्छी तरह से समझाया गया है, लेकिन मैं इस बात पर अधिक जोर देना चाहूँगा कि इसका हिस्सा क्यों है।

क्यों किसी भी OOP भाषा में बहुरूपता इतना महत्वपूर्ण है।

आइए इनहेरिटेंस / पॉलीमॉर्फिज्म के साथ और बिना टीवी के लिए एक सरल एप्लिकेशन बनाने का प्रयास करें। आवेदन के प्रत्येक संस्करण को पोस्ट करें, हम एक छोटे पूर्वव्यापी करते हैं।

मान लीजिए, आप एक टीवी कंपनी में सॉफ्टवेयर इंजीनियर हैं और आपसे यूजर कमांड पर उनके मूल्यों को बढ़ाने और घटाने के लिए वॉल्यूम, ब्राइटनेस और कलर कंट्रोलर्स के लिए सॉफ्टवेयर लिखने के लिए कहा जाता है।

आप जोड़कर इन सुविधाओं में से प्रत्येक के लिए लेखन कक्षाएं शुरू करते हैं

  1. सेट: - नियंत्रक का मान सेट करने के लिए। (मान लीजिए कि इसमें नियंत्रक विशिष्ट कोड है)
  2. get: - नियंत्रक का मान प्राप्त करने के लिए। (मान लीजिए कि इसमें नियंत्रक विशिष्ट कोड है)
  3. समायोजित करें: - इनपुट को मान्य करने के लिए और एक नियंत्रक स्थापित करने के लिए। (सामान्य सत्यापन .. नियंत्रक से स्वतंत्र)
  4. कंट्रोलर के साथ यूजर इनपुट मैपिंग: - यूजर इनपुट प्राप्त करने के लिए और तदनुसार नियंत्रकों को लागू करने के लिए।

अनुप्रयोग संस्करण 1

import java.util.Scanner;    
class VolumeControllerV1 {
    private int value;
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of VolumeController \t"+this.value);
        this.value = value;
        System.out.println("New value of VolumeController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}
class  BrightnessControllerV1 {
    private int value;
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of BrightnessController \t"+this.value);
        this.value = value;
        System.out.println("New value of BrightnessController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}
class ColourControllerV1    {
    private int value;
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of ColourController \t"+this.value);
        this.value = value;
        System.out.println("New value of ColourController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}

/*
 *       There can be n number of controllers
 * */
public class TvApplicationV1 {
    public static void main(String[] args)  {
        VolumeControllerV1 volumeControllerV1 = new VolumeControllerV1();
        BrightnessControllerV1 brightnessControllerV1 = new BrightnessControllerV1();
        ColourControllerV1 colourControllerV1 = new ColourControllerV1();


        OUTER: while(true) {
            Scanner sc=new Scanner(System.in);
            System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
            System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
            System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
            System.out.println("Press any other Button to shutdown");
            int button = sc.nextInt();
            switch (button) {
                case  1:    {
                    volumeControllerV1.adjust(5);
                    break;
                }
                case 2: {
                    volumeControllerV1.adjust(-5);
                    break;
                }
                case  3:    {
                    brightnessControllerV1.adjust(5);
                    break;
                }
                case 4: {
                    brightnessControllerV1.adjust(-5);
                    break;
                }
                case  5:    {
                    colourControllerV1.adjust(5);
                    break;
                }
                case 6: {
                colourControllerV1.adjust(-5);
                break;
            }
            default:
                System.out.println("Shutting down...........");
                break OUTER;
        }

    }
    }
}

अब आपके पास काम करने के लिए तैयार किया गया हमारा पहला संस्करण है। अब तक किए गए कार्य का विश्लेषण करने का समय।

टीवी अनुप्रयोग संस्करण 1 में समस्याएँ

  1. तीनों वर्गों में समायोजन (इंट वैल्यू) कोड डुप्लिकेट है। आप कोड डुप्लिकेट को कम करना चाहेंगे। (लेकिन आपने कॉमन कोड के बारे में नहीं सोचा और डुप्लिकेट कोड से बचने के लिए इसे किसी सुपर क्लास में ले गए)

जब तक आपका एप्लिकेशन उम्मीद के मुताबिक काम करता है, तब तक आप उसके साथ रहने का फैसला करते हैं।

कभी-कभी, आपका बॉस आपके पास वापस आ जाता है और आपसे मौजूदा एप्लिकेशन में रीसेट कार्यक्षमता जोड़ने के लिए कहता है। रीसेट सभी 3 तीन नियंत्रक को उनके संबंधित डिफ़ॉल्ट मानों पर सेट करेगा।

आप नई कार्यक्षमता के लिए एक नया वर्ग (ResetFunctionV2) लिखना शुरू करते हैं और इस नई सुविधा के लिए उपयोगकर्ता इनपुट मैपिंग कोड को मैप करते हैं।

अनुप्रयोग संस्करण 2

import java.util.Scanner;
class VolumeControllerV2    {

    private int defaultValue = 25;
    private int value;

    int getDefaultValue() {
        return defaultValue;
    }
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of VolumeController \t"+this.value);
        this.value = value;
        System.out.println("New value of VolumeController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}
class  BrightnessControllerV2   {

    private int defaultValue = 50;
    private int value;
    int get()    {
        return value;
    }
    int getDefaultValue() {
        return defaultValue;
    }
    void set(int value) {
        System.out.println("Old value of BrightnessController \t"+this.value);
        this.value = value;
        System.out.println("New value of BrightnessController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}
class ColourControllerV2    {

    private int defaultValue = 40;
    private int value;
    int get()    {
        return value;
    }
    int getDefaultValue() {
        return defaultValue;
    }
    void set(int value) {
        System.out.println("Old value of ColourController \t"+this.value);
        this.value = value;
        System.out.println("New value of ColourController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}

class ResetFunctionV2 {

    private VolumeControllerV2 volumeControllerV2 ;
    private BrightnessControllerV2 brightnessControllerV2;
    private ColourControllerV2 colourControllerV2;

    ResetFunctionV2(VolumeControllerV2 volumeControllerV2, BrightnessControllerV2 brightnessControllerV2, ColourControllerV2 colourControllerV2)  {
        this.volumeControllerV2 = volumeControllerV2;
        this.brightnessControllerV2 = brightnessControllerV2;
        this.colourControllerV2 = colourControllerV2;
    }
    void onReset()    {
        volumeControllerV2.set(volumeControllerV2.getDefaultValue());
        brightnessControllerV2.set(brightnessControllerV2.getDefaultValue());
        colourControllerV2.set(colourControllerV2.getDefaultValue());
    }
}
/*
 *       so on
 *       There can be n number of controllers
 *
 * */
public class TvApplicationV2 {
    public static void main(String[] args)  {
        VolumeControllerV2 volumeControllerV2 = new VolumeControllerV2();
        BrightnessControllerV2 brightnessControllerV2 = new BrightnessControllerV2();
        ColourControllerV2 colourControllerV2 = new ColourControllerV2();

        ResetFunctionV2 resetFunctionV2 = new ResetFunctionV2(volumeControllerV2, brightnessControllerV2, colourControllerV2);

        OUTER: while(true) {
            Scanner sc=new Scanner(System.in);
            System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
            System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
            System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
            System.out.println(" Press 7 to reset TV \n Press any other Button to shutdown");
            int button = sc.nextInt();
            switch (button) {
                case  1:    {
                    volumeControllerV2.adjust(5);
                    break;
                }
                case 2: {
                    volumeControllerV2.adjust(-5);
                    break;
                }
                case  3:    {
                    brightnessControllerV2.adjust(5);
                    break;
                }
                case 4: {
                    brightnessControllerV2.adjust(-5);
                    break;
                }
                case  5:    {
                    colourControllerV2.adjust(5);
                    break;
                }
                case 6: {
                    colourControllerV2.adjust(-5);
                    break;
                }
                case 7: {
                    resetFunctionV2.onReset();
                    break;
                }
                default:
                    System.out.println("Shutting down...........");
                    break OUTER;
            }

        }
    }
}

तो आप अपने आवेदन रीसेट सुविधा के साथ तैयार है। लेकिन, अब आपको यह एहसास होने लगा है

टीवी अनुप्रयोग संस्करण 2 में समस्याएँ

  1. यदि उत्पाद के लिए एक नया नियंत्रक पेश किया जाता है, तो आपको रीसेट सुविधा कोड बदलना होगा।
  2. यदि नियंत्रक की गिनती बहुत अधिक बढ़ जाती है, तो आपको नियंत्रकों के संदर्भों को रखने में समस्या होगी।
  3. रिसेट फीचर कोड को सभी कंट्रोलर्स क्लास के कोड (डिफ़ॉल्ट मान प्राप्त करने और सेट करने के लिए) के साथ कसकर जोड़ा जाता है।
  4. रीसेट सुविधा वर्ग (ResetFunctionV2) नियंत्रक वर्ग के अन्य तरीके (समायोजन) तक पहुंच सकता है जो अवांछनीय है।

उसी समय, आप बॉस से सुनते हैं कि आपको स्टार्ट-अप पर प्रत्येक कंट्रोलर, जिसमें इंटरनेट के माध्यम से कंपनी के होस्ट किए गए ड्राइवर रिपॉजिटरी से ड्राइवर के नवीनतम संस्करण की जाँच करने की आवश्यकता है, एक फीचर जोड़ना होगा।

अब आप यह सोचना शुरू करते हैं कि यह नया फीचर रिसेट फीचर से मिलता जुलता है और एप्लीकेशन (V2) के इश्यू कई गुना हो जाएंगे, यदि आप अपने एप्लिकेशन को दोबारा नहीं लगाते हैं।

आप विरासत का उपयोग करने के बारे में सोचना शुरू करते हैं ताकि आप JAVA की बहुरूपी क्षमता का लाभ उठा सकें और आप एक नया सार वर्ग (कंट्रोलर 3) जोड़ दें

  1. प्राप्त और निर्धारित विधि के हस्ताक्षर की घोषणा करें।
  2. कंटेनर को लागू करने की विधि को समायोजित करें जो पहले सभी नियंत्रकों के बीच दोहराया गया था।
  3. सेटलेफ़ॉल्ट विधि को घोषित करें ताकि रीसेट सुविधा को पॉलीमॉर्फिज़्म का लाभ उठाकर आसानी से लागू किया जा सके।

इन सुधारों के साथ, आपके पास आपके टीवी एप्लिकेशन का संस्करण 3 आपके साथ तैयार है।

अनुप्रयोग संस्करण 3

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

abstract class ControllerV3 {
    abstract void set(int value);
    abstract int get();
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
    abstract void setDefault();
}
class VolumeControllerV3 extends ControllerV3   {

    private int defaultValue = 25;
    private int value;

    public void setDefault() {
        set(defaultValue);
    }
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of VolumeController \t"+this.value);
        this.value = value;
        System.out.println("New value of VolumeController \t"+this.value);
    }
}
class  BrightnessControllerV3  extends ControllerV3   {

    private int defaultValue = 50;
    private int value;

    public void setDefault() {
        set(defaultValue);
    }
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of BrightnessController \t"+this.value);
        this.value = value;
        System.out.println("New value of BrightnessController \t"+this.value);
    }
}
class ColourControllerV3 extends ControllerV3   {

    private int defaultValue = 40;
    private int value;

    public void setDefault() {
        set(defaultValue);
    }
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of ColourController \t"+this.value);
        this.value = value;
        System.out.println("New value of ColourController \t"+this.value);
    }
}

class ResetFunctionV3 {

    private List<ControllerV3> controllers = null;

    ResetFunctionV3(List<ControllerV3> controllers)  {
        this.controllers = controllers;
    }
    void onReset()    {
        for (ControllerV3 controllerV3 :this.controllers)  {
            controllerV3.setDefault();
        }
    }
}
/*
 *       so on
 *       There can be n number of controllers
 *
 * */
public class TvApplicationV3 {
    public static void main(String[] args)  {
        VolumeControllerV3 volumeControllerV3 = new VolumeControllerV3();
        BrightnessControllerV3 brightnessControllerV3 = new BrightnessControllerV3();
        ColourControllerV3 colourControllerV3 = new ColourControllerV3();

        List<ControllerV3> controllerV3s = new ArrayList<>();
        controllerV3s.add(volumeControllerV3);
        controllerV3s.add(brightnessControllerV3);
        controllerV3s.add(colourControllerV3);

        ResetFunctionV3 resetFunctionV3 = new ResetFunctionV3(controllerV3s);

        OUTER: while(true) {
            Scanner sc=new Scanner(System.in);
            System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
            System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
            System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
            System.out.println(" Press 7 to reset TV \n Press any other Button to shutdown");
            int button = sc.nextInt();
            switch (button) {
                case  1:    {
                    volumeControllerV3.adjust(5);
                    break;
                }
                case 2: {
                    volumeControllerV3.adjust(-5);
                    break;
                }
                case  3:    {
                    brightnessControllerV3.adjust(5);
                    break;
                }
                case 4: {
                    brightnessControllerV3.adjust(-5);
                    break;
                }
                case  5:    {
                    colourControllerV3.adjust(5);
                    break;
                }
                case 6: {
                    colourControllerV3.adjust(-5);
                    break;
                }
                case 7: {
                    resetFunctionV3.onReset();
                    break;
                }
                default:
                    System.out.println("Shutting down...........");
                    break OUTER;
            }

        }
    }
}

हालाँकि V2 के अंक सूची में सूचीबद्ध अधिकांश मुद्दे को छोड़कर संबोधित किया गया था

टीवी अनुप्रयोग संस्करण 3 में समस्याएँ

  1. रीसेट सुविधा वर्ग (ResetFunctionV3) नियंत्रक वर्ग के अन्य तरीके (समायोजन) तक पहुंच सकता है जो अवांछनीय है।

फिर, आप इस समस्या को हल करने के बारे में सोचते हैं, क्योंकि अब आपके पास एक और विशेषता है (स्टार्टअप पर ड्राइवर अपडेट) के रूप में अच्छी तरह से लागू करने के लिए। यदि आप इसे ठीक नहीं करते हैं, तो यह नई सुविधाओं के लिए भी दोहराया जाएगा।

तो आप सार वर्ग में परिभाषित अनुबंध को विभाजित करते हैं और इसके लिए 2 इंटरफेस लिखते हैं

  1. सुविधा रीसेट करें।
  2. ड्राइवर अपडेट।

और अपने 1 ठोस वर्ग को नीचे के रूप में लागू करें

अनुप्रयोग संस्करण 4

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

interface OnReset {
    void setDefault();
}
interface OnStart {
    void checkForDriverUpdate();
}
abstract class ControllerV4 implements OnReset,OnStart {
    abstract void set(int value);
    abstract int get();
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}

class VolumeControllerV4 extends ControllerV4 {

    private int defaultValue = 25;
    private int value;
    @Override
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of VolumeController \t"+this.value);
        this.value = value;
        System.out.println("New value of VolumeController \t"+this.value);
    }
    @Override
    public void setDefault() {
        set(defaultValue);
    }

    @Override
    public void checkForDriverUpdate()    {
        System.out.println("Checking driver update for VolumeController .... Done");
    }
}
class  BrightnessControllerV4 extends ControllerV4 {

    private int defaultValue = 50;
    private int value;
    @Override
    int get()    {
        return value;
    }
    @Override
    void set(int value) {
        System.out.println("Old value of BrightnessController \t"+this.value);
        this.value = value;
        System.out.println("New value of BrightnessController \t"+this.value);
    }

    @Override
    public void setDefault() {
        set(defaultValue);
    }

    @Override
    public void checkForDriverUpdate()    {
        System.out.println("Checking driver update for BrightnessController .... Done");
    }
}
class ColourControllerV4 extends ControllerV4 {

    private int defaultValue = 40;
    private int value;
    @Override
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of ColourController \t"+this.value);
        this.value = value;
        System.out.println("New value of ColourController \t"+this.value);
    }
    @Override
    public void setDefault() {
        set(defaultValue);
    }

    @Override
    public void checkForDriverUpdate()    {
        System.out.println("Checking driver update for ColourController .... Done");
    }
}
class ResetFunctionV4 {

    private List<OnReset> controllers = null;

    ResetFunctionV4(List<OnReset> controllers)  {
        this.controllers = controllers;
    }
    void onReset()    {
        for (OnReset onreset :this.controllers)  {
            onreset.setDefault();
        }
    }
}
class InitializeDeviceV4 {

    private List<OnStart> controllers = null;

    InitializeDeviceV4(List<OnStart> controllers)  {
        this.controllers = controllers;
    }
    void initialize()    {
        for (OnStart onStart :this.controllers)  {
            onStart.checkForDriverUpdate();
        }
    }
}
/*
*       so on
*       There can be n number of controllers
*
* */
public class TvApplicationV4 {
    public static void main(String[] args)  {
        VolumeControllerV4 volumeControllerV4 = new VolumeControllerV4();
        BrightnessControllerV4 brightnessControllerV4 = new BrightnessControllerV4();
        ColourControllerV4 colourControllerV4 = new ColourControllerV4();
        List<ControllerV4> controllerV4s = new ArrayList<>();
        controllerV4s.add(brightnessControllerV4);
        controllerV4s.add(volumeControllerV4);
        controllerV4s.add(colourControllerV4);

        List<OnStart> controllersToInitialize = new ArrayList<>();
        controllersToInitialize.addAll(controllerV4s);
        InitializeDeviceV4 initializeDeviceV4 = new InitializeDeviceV4(controllersToInitialize);
        initializeDeviceV4.initialize();

        List<OnReset> controllersToReset = new ArrayList<>();
        controllersToReset.addAll(controllerV4s);
        ResetFunctionV4 resetFunctionV4 = new ResetFunctionV4(controllersToReset);

        OUTER: while(true) {
            Scanner sc=new Scanner(System.in);
            System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
            System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
            System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
            System.out.println(" Press 7 to reset TV \n Press any other Button to shutdown");
            int button = sc.nextInt();
            switch (button) {
                case  1:    {
                    volumeControllerV4.adjust(5);
                    break;
                }
                case 2: {
                    volumeControllerV4.adjust(-5);
                    break;
                }
                case  3:    {
                    brightnessControllerV4.adjust(5);
                    break;
                }
                case 4: {
                    brightnessControllerV4.adjust(-5);
                    break;
                }
                case  5:    {
                    colourControllerV4.adjust(5);
                    break;
                }
                case 6: {
                    colourControllerV4.adjust(-5);
                    break;
                }
                case 7: {
                    resetFunctionV4.onReset();
                    break;
                }
                default:
                    System.out.println("Shutting down...........");
                    break OUTER;
            }

        }
    }
}

अब आपके द्वारा सामना किए गए सभी मुद्दे को संबोधित किया गया और आपने महसूस किया कि विरासत और बहुरूपता के उपयोग के साथ आप कर सकते हैं

  1. एप्लिकेशन के विभिन्न भाग को शिथिल रखें। (रीसेट या ड्राइवर अपडेट सुविधा घटकों को वास्तविक नियंत्रक कक्षाओं (वॉल्यूम, चमक और रंग) से अवगत कराने की आवश्यकता नहीं है, ओनेसेट या ऑनस्टार्ट को लागू करने वाला कोई भी वर्ग रीसेट या ग्राहक सुविधा के लिए स्वीकार्य होगा। घटक क्रमशः)।
  2. एप्लिकेशन एन्हांसमेंट आसान हो जाता है! (कंट्रोलर वॉन्ट इफ़ेक्ट रिसेट या ड्राइवर अपडेट फ़ीचर घटक का नया जोड़, और अब आपके लिए नया जोड़ना आसान है)
  3. अमूर्तता की परत रखें। (अब रीसेट सुविधा केवल नियंत्रकों की सेटफॉल्ट पद्धति देख सकती है और रीसेट सुविधा केवल जांचकर्ताओं की नियंत्रक विधि को देख सकती है)

उम्मीद है की यह मदद करेगा :-)


3

ओवरलोडिंग शब्द एक ही नाम के साथ कुछ के कई संस्करण होने का संदर्भ देता है, आमतौर पर विभिन्न पैरामीटर सूचियों के साथ तरीके

public int DoSomething(int objectId) { ... }
public int DoSomething(string objectName) { ... }

तो ये कार्य समान कार्य कर सकते हैं लेकिन आपके पास इसे एक आईडी या एक नाम के साथ कॉल करने का विकल्प है। विरासत, अमूर्त वर्ग इत्यादि से कोई लेना-देना नहीं है।

ओवरराइडिंग आमतौर पर बहुरूपता को संदर्भित करता है, जैसा कि आपने अपने प्रश्न में वर्णित किया है


2

ओवरलोडिंग तब होती है जब आप एक ही नाम लेकिन विभिन्न मापदंडों के साथ 2 विधियों को परिभाषित करते हैं

ओवरराइडिंग वह जगह है जहां आप एक उप-वर्ग में एक ही नाम के साथ एक फ़ंक्शन के माध्यम से बेस क्लास के व्यवहार को बदलते हैं।

इसलिए बहुरूपता ओवरराइडिंग से संबंधित है लेकिन वास्तव में अतिभारित नहीं है।

हालांकि अगर किसी ने मुझे "क्या बहुरूपता है?" प्रश्न के लिए "ओवरराइडिंग" का एक सरल जवाब दिया। मैं और स्पष्टीकरण मांगूंगा।


2

ओवरराइडिंग एक विरासत के तरीके को छिपाने के समान है, समान नाम और हस्ताक्षर के साथ एक विधि को उच्च स्तर की विधि (सुपर विधि) घोषित करके, यह वर्ग के लिए एक बहुरूपी व्यवहार जोड़ता है। दूसरे शब्दों में कहा जा सकता है कि विच लेवल मेथड चुनने का फैसला रन टाइम पर किया जाएगा, न कि कंपाइल टाइम पर। यह इंटरफ़ेस और कार्यान्वयन की अवधारणा की ओर जाता है।


2

बहुरूपता क्या है?

जावा से ट्यूटोरियल से

बहुरूपता की शब्द परिभाषा जीव विज्ञान में एक सिद्धांत को संदर्भित करती है जिसमें एक जीव या प्रजाति के कई अलग-अलग रूप या चरण हो सकते हैं। इस सिद्धांत को ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग और जावा भाषा जैसी भाषाओं पर भी लागू किया जा सकता है। एक वर्ग के उपवर्ग अपने स्वयं के अनूठे व्यवहार को परिभाषित कर सकते हैं और फिर भी माता-पिता वर्ग की कुछ समान कार्यक्षमता को साझा कर सकते हैं।

उदाहरणों और परिभाषा पर विचार करके, ओवरराइडिंग को स्वीकार किया जाना चाहिए।

आपकी दूसरी क्वेरी के बारे में:

यदि आपके पास एक सार आधार वर्ग है जो बिना किसी कार्यान्वयन के एक विधि को परिभाषित करता है, और आपने उप-वर्ग में उस पद्धति को परिभाषित किया है, तो क्या यह अभी भी अधिरोहित है?

इसे ओवरराइडिंग कहा जाना चाहिए।

विभिन्न प्रकार के ओवरराइडिंग को समझने के लिए इस उदाहरण पर एक नज़र डालें।

  1. बेस क्लास कोई कार्यान्वयन प्रदान नहीं करता है और उप-वर्ग को पूरी विधि को ओवरराइड करना पड़ता है - (सार)
  2. बेस क्लास डिफ़ॉल्ट कार्यान्वयन प्रदान करता है और उप-वर्ग व्यवहार को बदल सकता है
  3. उप-वर्ग कॉल करके बेस क्लास कार्यान्वयन में विस्तार जोड़ता है super.methodName() पहले कथन के रूप में
  4. बेस क्लास एल्गोरिथम (टेम्पलेट विधि) की संरचना को परिभाषित करता है और उप-वर्ग एल्गोरिथ्म के एक हिस्से को ओवरराइड करेगा

सांकेतिक टुकड़ा:

import java.util.HashMap;

abstract class Game implements Runnable{

    protected boolean runGame = true;
    protected Player player1 = null;
    protected Player player2 = null;
    protected Player currentPlayer = null;

    public Game(){
        player1 = new Player("Player 1");
        player2 = new Player("Player 2");
        currentPlayer = player1;
        initializeGame();
    }

    /* Type 1: Let subclass define own implementation. Base class defines abstract method to force
        sub-classes to define implementation    
    */

    protected abstract void initializeGame();

    /* Type 2: Sub-class can change the behaviour. If not, base class behaviour is applicable */
    protected void logTimeBetweenMoves(Player player){
        System.out.println("Base class: Move Duration: player.PlayerActTime - player.MoveShownTime");
    }

    /* Type 3: Base class provides implementation. Sub-class can enhance base class implementation by calling
        super.methodName() in first line of the child class method and specific implementation later */
    protected void logGameStatistics(){
        System.out.println("Base class: logGameStatistics:");
    }
    /* Type 4: Template method: Structure of base class can't be changed but sub-class can some part of behaviour */
    protected void runGame() throws Exception{
        System.out.println("Base class: Defining the flow for Game:");  
        while ( runGame) {
            /*
            1. Set current player
            2. Get Player Move
            */
            validatePlayerMove(currentPlayer);  
            logTimeBetweenMoves(currentPlayer);
            Thread.sleep(500);
            setNextPlayer();
        }
        logGameStatistics();
    }
    /* sub-part of the template method, which define child class behaviour */
    protected abstract void validatePlayerMove(Player p);

    protected void setRunGame(boolean status){
        this.runGame = status;
    }
    public void setCurrentPlayer(Player p){
        this.currentPlayer = p;
    }
    public void setNextPlayer(){
        if ( currentPlayer == player1) {
            currentPlayer = player2;
        }else{
            currentPlayer = player1;
        }
    }
    public void run(){
        try{
            runGame();
        }catch(Exception err){
            err.printStackTrace();
        }
    }
}

class Player{
    String name;
    Player(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
}

/* Concrete Game implementation  */
class Chess extends Game{
    public Chess(){
        super();
    }
    public void initializeGame(){
        System.out.println("Child class: Initialized Chess game");
    }
    protected void validatePlayerMove(Player p){
        System.out.println("Child class: Validate Chess move:"+p.getName());
    }
    protected void logGameStatistics(){
        super.logGameStatistics();
        System.out.println("Child class: Add Chess specific logGameStatistics:");
    }
}
class TicTacToe extends Game{
    public TicTacToe(){
        super();
    }
    public void initializeGame(){
        System.out.println("Child class: Initialized TicTacToe game");
    }
    protected void validatePlayerMove(Player p){
        System.out.println("Child class: Validate TicTacToe move:"+p.getName());
    }
}

public class Polymorphism{
    public static void main(String args[]){
        try{

            Game game = new Chess();
            Thread t1 = new Thread(game);
            t1.start();
            Thread.sleep(1000);
            game.setRunGame(false);
            Thread.sleep(1000);

            game = new TicTacToe();
            Thread t2 = new Thread(game);
            t2.start();
            Thread.sleep(1000);
            game.setRunGame(false);

        }catch(Exception err){
            err.printStackTrace();
        }       
    }
}

उत्पादन:

Child class: Initialized Chess game
Base class: Defining the flow for Game:
Child class: Validate Chess move:Player 1
Base class: Move Duration: player.PlayerActTime - player.MoveShownTime
Child class: Validate Chess move:Player 2
Base class: Move Duration: player.PlayerActTime - player.MoveShownTime
Base class: logGameStatistics:
Child class: Add Chess specific logGameStatistics:
Child class: Initialized TicTacToe game
Base class: Defining the flow for Game:
Child class: Validate TicTacToe move:Player 1
Base class: Move Duration: player.PlayerActTime - player.MoveShownTime
Child class: Validate TicTacToe move:Player 2
Base class: Move Duration: player.PlayerActTime - player.MoveShownTime
Base class: logGameStatistics:

2

मुझे लगता है कि लोग आपकी अवधारणाओं को मिला रहे हैं। पॉलीमॉर्फिज्म किसी वस्तु की क्षमता है कि वह समय पर अलग-अलग व्यवहार करती है। इसे प्राप्त करने के लिए, आपको दो आवश्यकताएं चाहिए:

  1. देर से बांधना
  2. विरासत।

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

हालाँकि C ++ में ऐसा नहीं है। कोई भी अतिभारित विधि, स्वतंत्र रूप से कि क्या हस्ताक्षर समान है या नहीं (डिफरेंट राशि, विभिन्न प्रकार) भी ओवरराइड है । दिन के लिए, बेस क्लास की विधि अब उपवर्ग में उपलब्ध नहीं है, जब उपवर्ग ऑब्जेक्ट के बाहर से बुलाया जा रहा है, जाहिर है।

तो जवाब है जब जावा के बारे में बात करते हुए ओवरलोडिंग का उपयोग करें । किसी भी अन्य भाषा में अलग हो सकता है क्योंकि यह c ++ में होता है


1

पॉलीमॉर्फिज्म की संभावना अधिक है जहां तक ​​इसका अर्थ है है ... जावा में ओवरराइड करना

यह सभी अलग-अलग स्थितियों में एसएएमई ऑब्जेक्ट के अलग-अलग व्यवहार के बारे में है (प्रोग्रामिंग तरीके से ... आप अलग-अलग कॉल कर सकते हैं)

मुझे लगता है कि नीचे दिया गया उदाहरण आपको समझने में मदद करेगा ... हालाँकि यह PURE java code नहीं है ...

     public void See(Friend)
     {
        System.out.println("Talk");
     }

लेकिन अगर हम ARGUMENT बदल देते हैं ... BEHAVIOR को बदल दिया जाएगा ...

     public void See(Enemy)
     {
        System.out.println("Run");
     }

व्यक्ति (यहां "ऑब्जेक्ट") समान है ...


1

बहुरूपता एक वस्तु का एक बहु कार्यान्वयन है या आप एक वस्तु के कई रूप कह सकते हैं। मान लें कि आपके पास Animalsसार आधार वर्ग के रूप में कक्षा है और इसमें एक विधि है जिसे कहा जाता है movement()जो जानवर को स्थानांतरित करने के तरीके को परिभाषित करता है। अब वास्तव में हमारे पास विभिन्न प्रकार के जानवर हैं और वे अलग-अलग तरह से चलते हैं जिनमें से 2 पैर, 4 अन्य के साथ कुछ और कुछ पैरों के साथ नहीं हैं, आदि .. movement()पृथ्वी पर प्रत्येक जानवर के अलग-अलग परिभाषित करने के लिए , हमें बहुरूपता को लागू करने की आवश्यकता है। हालाँकि, आपको अधिक कक्षाएं यानी क्लास Dogs Cats Fishआदि को परिभाषित करने की आवश्यकता है फिर आपको उन कक्षाओं को बेस क्लास से आगे बढ़ाने Animalsऔर इसकी विधि को ओवरराइड करने की आवश्यकता हैmovement() आपके पास प्रत्येक जानवर के आधार पर एक नई गति कार्यक्षमता के साथ को करना होगा। आप भी उपयोग कर सकते हैंInterfacesउस को प्राप्त करने के लिए। यहाँ कीवर्ड ओवरराइडिंग है, ओवरलोडिंग अलग है और इसे बहुरूपता नहीं माना जाता है। ओवरलोडिंग के साथ आप "एक ही नाम के साथ" कई विधियों को परिभाषित कर सकते हैं लेकिन एक ही वस्तु या वर्ग पर अलग-अलग मापदंडों के साथ।


0

बहुरूपता भाषा का एक एकल इंटरफेस का उपयोग करके समान रूप से अलग वस्तु का इलाज करने की क्षमता से संबंधित है; जैसा कि यह ओवरराइडिंग से संबंधित है, इसलिए इंटरफ़ेस (या बेस क्लास) बहुरूपी है, कार्यान्वयनकर्ता वह वस्तु है जो ओवरराइड करता है (एक ही पदक के दो चेहरे)

वैसे भी, दो भाषाओं के बीच अंतर को अन्य भाषाओं का उपयोग करके बेहतर तरीके से समझाया गया है, जैसे कि c ++: c ++ में एक बहुरूपी वस्तु जावा काउंटरपार्ट के रूप में व्यवहार करती है यदि बेस फ़ंक्शन आभासी है, लेकिन यदि विधि वर्चुअल नहीं है तो कोड जम्प स्टेटिक रूप से हल हो जाता है , और रनटाइम पर सही प्रकार की जाँच नहीं की गई है, बहुरूपता में किसी वस्तु के लिए अलग तरीके से व्यवहार करने की क्षमता शामिल होती है जो उस तक पहुँचने के लिए उपयोग किए गए इंटरफ़ेस के आधार पर होती है; मुझे pseudocode में एक उदाहरण बनाने दें:

class animal {
    public void makeRumor(){
        print("thump");
    }
}
class dog extends animal {
    public void makeRumor(){
        print("woff");
    }
}

animal a = new dog();
dog b = new dog();

a.makeRumor() -> prints thump
b.makeRumor() -> prints woff

(यह मानते हुए कि मेकअॉर वर्चुअल नहीं है)

जावा वास्तव में बहुरूपता के इस स्तर की पेशकश नहीं करता है (जिसे ऑब्जेक्ट स्लाइसिंग भी कहा जाता है)।

जानवर a = नया कुत्ता (); dog b = नया कुत्ता ();

a.makeRumor() -> prints thump
b.makeRumor() -> prints woff

दोनों ही स्थिति में यह केवल woff प्रिंट करेगा .. क्योंकि a और b क्लास के कुत्ते को संदर्भित कर रहा है



जानवर a = नया कुत्ता (); एक कुत्ते के रूप में निर्माण किया गया था, और "woff" मुद्रित करेगा। यदि आप चाहते हैं कि यह थम्प प्रिंट करे, तो आपको इसे बनाए रखने की आवश्यकता है। ((पशु) a) .makeRumor ()
क्रिस

यह संदर्भ को बनाए रखने है, लेकिन वस्तु अभी भी एक कुत्ता है। यदि आप चाहते हैं कि यह एक जानवर हो, तो आपको स्पष्ट रूप से ऑब्जेक्ट को ऊपर करना होगा।
क्रिस कूडम सोर

पता लगा लिया। प्रश्न जावा को टैग किया गया था। आपने C ++ का उत्तर दिया। आप C ++ में सही हो सकते हैं। मैं निश्चित रूप से जावा में सही हूं।
क्रिस कॉडमोर

हर बार ऐसा होना चाहिए कि एक कॉपी कंस्ट्रक्टर यहां शामिल हो, एक संदर्भ है fredosaurus.com/notes-cpp/oop-condestructors/… केस तीन मैच; नए ऑपरेटर को अनदेखा करें जो कि केवल सृजन को खंडित करने के लिए है।
लोरेंजो बोकासिया 20

0
import java.io.IOException;

class Super {

    protected Super getClassName(Super s) throws IOException {
        System.out.println(this.getClass().getSimpleName() + " - I'm parent");
        return null;
    }

}

class SubOne extends Super {

    @Override
    protected Super getClassName(Super s)  {
        System.out.println(this.getClass().getSimpleName() + " - I'm Perfect Overriding");
        return null;
    }

}

class SubTwo extends Super {

    @Override
    protected Super getClassName(Super s) throws NullPointerException {
        System.out.println(this.getClass().getSimpleName() + " - I'm Overriding and Throwing Runtime Exception");
        return null;
    }

}

class SubThree extends Super {

    @Override
    protected SubThree getClassName(Super s) {
        System.out.println(this.getClass().getSimpleName()+ " - I'm Overriding and Returning SubClass Type");
        return null;
    }

}

class SubFour extends Super {

    @Override
    protected Super getClassName(Super s) throws IOException {
        System.out.println(this.getClass().getSimpleName()+ " - I'm Overriding and Throwing Narrower Exception ");
        return null;
    }

}

class SubFive extends Super {

    @Override
    public Super getClassName(Super s) {
        System.out.println(this.getClass().getSimpleName()+ " - I'm Overriding and have broader Access ");
        return null;
    }

}

class SubSix extends Super {

    public Super getClassName(Super s, String ol) {
        System.out.println(this.getClass().getSimpleName()+ " - I'm Perfect Overloading ");
        return null;
    }

}

class SubSeven extends Super {

    public Super getClassName(SubSeven s) {
        System.out.println(this.getClass().getSimpleName()+ " - I'm Perfect Overloading because Method signature (Argument) changed.");
        return null;
    }

}

public class Test{

    public static void main(String[] args) throws Exception {

        System.out.println("Overriding\n");

        Super s1 = new SubOne(); s1.getClassName(null);

        Super s2 = new SubTwo(); s2.getClassName(null);

        Super s3 = new SubThree(); s3.getClassName(null);

        Super s4 = new SubFour(); s4.getClassName(null);

        Super s5 = new SubFive(); s5.getClassName(null);

        System.out.println("Overloading\n");

        SubSix s6 = new SubSix(); s6.getClassName(null, null);

        s6 = new SubSix(); s6.getClassName(null);

        SubSeven s7 = new SubSeven(); s7.getClassName(s7);

        s7 = new SubSeven(); s7.getClassName(new Super());

    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.