2010-01-17 21 views
24

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

+1

यहां देखें: http://stackoverflow.com/questions/409969/polymorphism-define-in-just- दो-वाक्य – Zaki

+1

मैं http://stackoverflow.com/questions/5854581/polymorphism-in-c/5854862#5854862 पर इस प्रश्न का उत्तर देने का प्रयास करता हूं - हालांकि यह polymorphism के लिए C++ समर्थन पर केंद्रित है, और अन्य भाषाओं में उप- या उल्लेख की गई सुविधाओं का सुपर सेट। मुझे लगता है कि यह अवधारणा को अच्छी तरह से कवर करता है हालांकि ... उम्मीद है कि यह मदद करता है। –

उत्तर

21

क्लासिक उत्तर: बेस श्रेणी Shape की कल्पना करें। यह GetArea विधि का खुलासा करता है। Square कक्षा और Rectangle कक्षा, और Circle कक्षा की कल्पना करें। अलग GetSquareArea, GetRectangleArea और GetCircleArea विधियों को बनाने के बजाय, आप व्युत्पन्न कक्षाओं में से केवल एक विधि को लागू करने के लिए मिलता है। आपको यह जानने की ज़रूरत नहीं है कि आप Shape का सटीक सबक्लास उपयोग करते हैं, आप बस GetArea पर कॉल करते हैं और आपको अपना परिणाम मिलता है, यह किस ठोस प्रकार से स्वतंत्र है। है

#include <iostream> 
using namespace std; 

class Shape 
{ 
public: 
    virtual float GetArea() = 0; 
}; 

class Rectangle : public Shape 
{ 
public: 
    Rectangle(float a) { this->a = a; } 
    float GetArea() { return a * a; } 
private: 
    float a; 
}; 

class Circle : public Shape 
{ 
public: 
    Circle(float r) { this->r = r; } 
    float GetArea() { return 3.14f * r * r; } 
private: 
    float r; 
}; 

int main() 
{ 
    Shape *a = new Circle(1.0f); 
    Shape *b = new Rectangle(1.0f); 

    cout << a->GetArea() << endl; 
    cout << b->GetArea() << endl; 
} 

यहाँ सूचना के लिए एक महत्वपूर्ण बात - आप वर्ग आप उपयोग कर रहे हैं, बस आधार प्रकार का सही प्रकार पता करने के लिए नहीं है, और:

इस कोड पर एक नज़र डालें आपको सही परिणाम मिल जाएगा। यह अधिक जटिल प्रणालियों में भी बहुत उपयोगी है।

मज़े सीखना है!

+0

मुझे लगता है कि क्लासिक "अंडाकार समस्या" के कारण आयताकार/मंडल एक खराब उदाहरण है, यह स्वाभाविक रूप से होता है। मान लें कि आपके पास एक आयताकार वर्ग है जिसके साथ आप चौड़ाई और ऊंचाई सेट कर सकते हैं, फिर आयताकार से विस्तारित एक वर्ग वर्ग जो एक ही समय में चौड़ाई और ऊंचाई निर्धारित करता है। फिर rect.Width * = 2; rect.Height * = 2; वास्तव में आपको 4x साइड लम्बाई देता है। – Warty

+0

@ किसी भी व्यक्ति के लिए लिस्कोव प्रतिस्थापन सिद्धांत के लिए इस खोज में और अधिक पढ़ना चाहते हैं। –

1

पॉलिमॉर्फिज्म आपको ऑब्जेक्ट्स का उपयोग करने वाले कोड लिखने की अनुमति देता है। इसके बाद आप बाद में नए वर्ग बना सकते हैं कि आपका मौजूदा कोड बिना किसी संशोधन के उपयोग कर सकता है।

उदाहरण के लिए, मान लीजिए कि आपके पास Lib2Groc(vehicle) फ़ंक्शन है जो पुस्तकालय से किराने की दुकान में वाहन चलाता है। इसे बाएं मुड़ने के लिए वाहनों को बताने की जरूरत है, इसलिए यह अन्य चीजों के साथ वाहन वस्तु पर TurnLeft() पर कॉल कर सकता है। फिर अगर कोई होवरक्राफ्ट की तरह एक नया वाहन खोजता है, तो इसका उपयोग Lib2Groc द्वारा बिना किसी संशोधन के किया जा सकता है।

0

आपको बहुरूपता की आवश्यकता नहीं है।

जब तक आप ऐसा नहीं करते हैं।

फिर इसके friggen भयानक।

सरल जवाब है कि आप समय की बहुत सारी के साथ सौदा होगा:

किसी सामान का एक संग्रह के माध्यम से जाने की जरूरत है। मान लें कि वे MySpecializedCollectionOfAwesome प्रकार के संग्रह के लिए पूछते हैं। लेकिन आप सूची के रूप में बहुत बढ़िया उदाहरणों से निपट रहे हैं। तो, अब, आपको एमएससीओए का एक उदाहरण बनाना होगा और इसे अपनी सूची < टी> में बहुत बढ़िया उदाहरण के साथ भरना होगा। बट में बड़ा दर्द, है ना?

ठीक है, अगर उन्होंने एक आईनेमरेबल < बहुत बढ़िया> के लिए कहा है, तो आप उन्हें बहुत सारे संग्रहों में से एक को सौंप सकते हैं। आप उन्हें एक सरणी (बहुत बढ़िया []) या एक सूची (सूची < विस्मयकारी>) या अजीब या किसी भी प्रकार के एक अवलोकन संग्रह को सौंप सकते हैं, आप उस उपकरण में अपने बहुत बढ़िया रहते हैं Inumerable < टी>।

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

7

सख्ती से टाइप की गई भाषा में, विभिन्न प्रकार की वस्तुओं की सूची/संग्रह/सरणी रखने के लिए बहुरूपता महत्वपूर्ण है। ऐसा इसलिए है क्योंकि सूचियां/सरणी स्वयं को सही प्रकार की वस्तुओं को रखने के लिए टाइप की जाती हैं।

उदाहरण के लिए हम निम्न है कल्पना कीजिए:

// the following is pseudocode M'kay: 
class apple; 
class banana; 
class kitchenKnife; 

apple foo; 
banana bar; 
kitchenKnife bat; 

apple *shoppingList = [foo, bar, bat]; // this is illegal because bar and bat is 
             // not of type apple. 

इसे सुलझाने के लिए:

class groceries; 
class apple inherits groceries; 
class banana inherits groceries; 
class kitchenKnife inherits groceries; 

apple foo; 
banana bar; 
kitchenKnife bat; 

groceries *shoppingList = [foo, bar, bat]; // this is OK 

यह भी और अधिक सरल आइटमों की सूची के प्रसंस्करण में आता है। उदाहरण के लिए कहो सब किराने का सामान विधि price() लागू करता है, प्रसंस्करण इस आसान है:

int total = 0; 
foreach (item in shoppingList) { 
    total += item.price(); 
} 

इन दो सुविधाओं क्या बहुरूपता करता है का केंद्र रहे।

4

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

  1. विरासत
  2. अधिभावी/लागू करने जनक कक्षा व्यवहार
  3. रनटाइम ऑब्जेक्ट बाध्यकारी

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

public interface DBOperation { 
    public void addEmployee(Employee newEmployee); 
    public void modifyEmployee(int id, Employee newInfo); 
    public void deleteEmployee(int id); 
} 

अब आप एक से अधिक कार्यान्वयन हो सकता है, मान लीजिए कि हम और आरडीबीएमएस के लिए एक प्रत्यक्ष फ़ाइल-प्रणाली के लिए अन्य

public class DBOperation_RDBMS implements DBOperation 
    // implements DBOperation above stating that you intend to implement all 
    // methods in DBOperation 
    public void addEmployee(Employee newEmployee) { 
      // here I would get JDBC (Java's Interface to RDBMS) handle 
      // add an entry into database table. 
    } 
    public void modifyEmployee(int id, Employee newInfo) { 
      // here I use JDBC handle to modify employee, and id to index to employee 
    } 
    public void deleteEmployee(int id) { 
      // here I would use JDBC handle to delete an entry 
    } 
} 

है की सुविधा देता है फाइल सिस्टम डेटाबेस कार्यान्वयन

public class DBOperation_FileSystem implements DBOperation 
    public void addEmployee(Employee newEmployee) { 
      // here I would Create a file and add a Employee record in to it 
    } 
    public void modifyEmployee(int id, Employee newInfo) { 
      // here I would open file, search for record and change values 
    } 
    public void deleteEmployee(int id) { 
      // here I search entry by id, and delete the record 
    } 
} 

देखते हैं कि कैसे मुख्य बीच दो

public class Main { 
    public static void main(String[] args) throws Exception { 
      Employee emp = new Employee(); 
      ... set employee information 

      DBOperation dboper = null; 
      // declare your db operation object, not there is no instance 
      // associated with it 

      if(args[0].equals("use_rdbms")) { 
       dboper = new DBOperation_RDBMS(); 
       // here conditionally, i.e when first argument to program is 
       // use_rdbms, we instantiate RDBM implementation and associate 
       // with variable dboper, which delcared as DBOperation. 
       // this is where runtime binding of polymorphism kicks in 
       // JVM is allowing this assignment because DBOperation_RDBMS 
       // has a "is a" relationship with DBOperation. 
      } else if(args[0].equals("use_fs")) { 
       dboper = new DBOperation_FileSystem(); 
       // similarly here conditionally we assign a different instance. 
      } else { 
       throw new RuntimeException("Dont know which implemnation to use"); 
      } 

      dboper.addEmployee(emp); 
      // now dboper is refering to one of the implementation 
      // based on the if conditions above 
      // by this point JVM knows dboper variable is associated with 
      // 'a' implemenation, and it will call appropriate method    
    } 
} 

आप कई स्थानों में बहुरूपता अवधारणा का उपयोग कर सकते हैं, एक praticle उदाहरण होगा स्विच कर सकते हैं देता है: की मदद से आप छवि decorer लिख रहे हैं, और आप छवियों ऐसे की पूरी गुच्छा समर्थन करने की आवश्यकता जेपीजी, टीआईएफ, पीएनजी इत्यादि के रूप में आपका आवेदन एक इंटरफेस को परिभाषित करेगा और सीधे उस पर काम करेगा। और आपके पास प्रत्येक जेपीजी, टीआईएफ, पीएनजी इत्यादि के लिए विभिन्न कार्यान्वयन के कुछ रनटाइम बाध्यकारी होंगे।

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

+0

अच्छा! वही है जो मैंने उपरोक्त मेरे उत्तर को संदर्भित किया है। यह सही कार्यों की गतिशील कॉलिंग में मदद करता है। ! –

0

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

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

यदि आप एक स्क्वायर, त्रिकोण या आयताकार परवाह नहीं करते हैं तो आपको परवाह नहीं होगा। आप बस क्षेत्र के बारे में परवाह करते हैं।इसलिए प्राप्त एरिया विधि को गतिशील वस्तु के आधार पर बुलाया जाएगा।

16

क्या आपने कभी + के साथ दो पूर्णांक जोड़े हैं, और फिर बाद में + के साथ एक फ़्लोटिंग-पॉइंट नंबर पर एक पूर्णांक जोड़ा?

क्या आपने कभी कुछ डीबग करने में मदद के लिए x.toString() लॉग किया है?

मुझे लगता है कि आप संभवतः नाम को जानने के बिना बहुरूपता की सराहना करते हैं।

0

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

जो हम पॉलिमॉर्फिज्म से चाहते हैं - हमारे डिजाइन निर्णय को सरल बनाते हैं और हमारे डिजाइन को अधिक विस्तारणीय और सुरुचिपूर्ण बनाते हैं। आपको ओपन-क्लोज़ेड सिद्धांत (http://en.wikipedia.org/wiki/Open/closed_principle) और सॉलिड (http://en.wikipedia.org/wiki/Solid_%28Object_Oriented_Design%29) पर भी ध्यान आकर्षित करना चाहिए जो आपको प्रमुख ओओ सिद्धांतों को समझने में मदद कर सकता है।

पीएस मुझे लगता है कि आप "गतिशील बहुरूपता" (http://en.wikipedia.org/wiki/Dynamic_polymorphism) के बारे में बात कर रहे हैं, क्योंकि "स्टेटिक पॉलिमॉर्फिज्म" जैसी ऐसी चीजें हैं (http://en.wikipedia.org/wiki/Template_metaprogramming#Static_polymorphism)।

5

पॉलिमॉर्फिज्म का लाभ क्लाइंट कोड को किसी विधि के वास्तविक कार्यान्वयन की परवाह करने की आवश्यकता नहीं है। निम्नलिखित उदाहरण देखें। यहां कारबिल्डर को उत्पादकार() के बारे में कुछ भी पता नहीं है। एक बार इसे कारों की सूची दी जाती है (CarsToProduceList) यह तदनुसार सभी आवश्यक कारों का उत्पादन करेगी।

class CarBase 
{ 
    public virtual void ProduceCar() 
    { 
     Console.WriteLine("don't know how to produce"); 
    } 
} 

class CarToyota : CarBase 
{ 
    public override void ProduceCar() 
    { 
     Console.WriteLine("Producing Toyota Car "); 
    } 
} 

class CarBmw : CarBase 
{ 
    public override void ProduceCar() 
    { 
     Console.WriteLine("Producing Bmw Car"); 
    } 
} 

class CarUnknown : CarBase { } 

class CarBuilder 
{ 
    public List<CarBase> CarsToProduceList { get; set; } 

    public void ProduceCars() 
    { 
     if (null != CarsToProduceList) 
     { 
      foreach (CarBase car in CarsToProduceList) 
      { 
       car.ProduceCar();// doesn't know how to produce 
      } 
     } 

    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     CarBuilder carbuilder = new CarBuilder(); 
     carbuilder.CarsToProduceList = new List<CarBase>() { new CarBmw(), new CarToyota(), new CarUnknown() };    
     carbuilder.ProduceCars(); 
    } 
} 
0

टैब किए गए आवेदन

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

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