2011-04-04 17 views
9

मुझे पता है कि बहुरूपता क्या है लेकिन इसे स्पष्ट रूप से समझने में असफल रहा। इसके अलावा मेरे कोड पीछा कर रहा है:क्या यह बहुरूपता का उदाहरण है?

class Human 
{ 
    public virtual void CleanTheRoom() 
    { 
    } 
} 
class Woman:Human 
{ 
    public override void CleanTheRoom() 
    { 
    //women clean faster 
    } 
} 
class Man:Human 
{ 
    public override void CleanTheRoom() 
    { 
    //men clean slower, different code here 
    } 
} 
class Child:Human 
{ 
    public override void CleanTheRoom() 
    { 
    //empty ... children are lazy :) 
    } 
} 

मैं समझाता चाहिए इस polymorhism है, क्योंकि आधार वर्ग मानव से सभी व्युत्पन्न वर्ग विधि CleanTheRoom हैं, लेकिन उनमें से प्रत्येक इसे दूसरे तरीके से लागू करता है?

+1

बेहतर स्टिल क्लीनररूम विधि परिभाषा को 'आईसीलीन' इंटरफ़ेस में रखना होगा और इसे लागू करने वाले मनुष्यों के प्रकारों के लिए लागू करना होगा। फिर आप इन इंसानों को इस इंटरफेस में डालने में सक्षम होने से मुक्त बहुलकवाद प्राप्त करते हैं। – ChristopheD

+29

यह निश्चित रूप से कामुकता का एक उदाहरण है। – juharr

+1

@juharr और agism। – kenny

उत्तर

21

पॉलिमॉर्फिज्म का लाभ तब आता है जब आप CleanTheRoom() को किसी प्रकार के Human पर विधि का आह्वान करना चाहते हैं, लेकिन आपको विशेष रूप से कोई परवाह नहीं है।

CleanTheRoom() आधार वर्ग स्तर, Human में परिभाषित होने पर, आपको कम, क्लीनर कोड अपने आवेदन में कहीं और लिख सकते हैं जब भी आप Human का एक उदाहरण के साथ काम कर रहे हैं, चाहे वह एक Man, Woman, या Child हो।

बहुरूपता, उदाहरण के लिए, की मदद से आप बदसूरत सशर्त बयान से बचने के जहां आप स्पष्ट रूप से Human के प्रत्येक प्रकार के लिए जाँच करें और एक भिन्न तरीके से कहते हैं:

अच्छा:

private void SomeMethod(Human h) 
{ 
    //some logic 
    h.CleanTheRoom(); 
    //more logic 
} 

बुरा:

private void SomeMethod(Human h) 
{ 
    //some logic 
    if (h is Man) 
     CleanRoomSlowly(); 
    else if (h is Woman) 
     CleanRoomQuickly(); 
    else if (h is Child) 
     GoofOff(); 
    //some logic 
} 
+0

यह भी एक अच्छा जवाब है, उसी कारण से जैकबॉम को टिप्पणी में व्यक्त किया गया। – riwalk

16

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

List<Human> humans = new ArrayList<Human>(); 

humans.add(new Woman()); 
humans.add(new Woman()); 
humans.add(new Man()); 
humans.add(new Child()); 
humans.add(new Child()); 

foreach(Human hum in humans) { 
    hum.CleanTheRoom(); //I don't know the type of hum, but I don't care 
} 

मैं विभिन्न स्थानों से मानव के उदाहरण का संग्रह किया गया है कहो - मैं हर एक है कि किस प्रकार पता नहीं है। लेकिन मैं अभी भी उन पर पुन: प्रयास कर सकता हूं और CleanTheRoom() को कॉल कर सकता हूं, क्योंकि वे एक अभिभावक वर्ग साझा करते हैं।

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

+1

यह मेरी राय में सबसे अच्छा जवाब है। बहुरूपता का मूल्य स्पष्ट हो जाता है जब आप इसे * इस्तेमाल * देखते हैं, न कि जब आप इसे * परिभाषित * देखते हैं। – riwalk

+0

मेरी इच्छा है कि पॉलिमॉर्फिज्म के साथ विरासत का वर्णन करने के लिए एक संक्षिप्त शब्द था। क्या कोई है? – Daisetsu

+1

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

0

हाँ, यह सही है। और आप यह जानने के बिना क्लीनररूम() विधि को कॉल कर सकते हैं कि यह किस तरह का "दयालु" है।

Here आपके पास कुछ बुनियादी उदाहरण हैं।

0

मुझे लगता है कि आप लाभ देखने में विफल रहते हैं, यही वह कुंजी है जिसे आप पूरी तरह से बहुरूपता को समझने के लिए गायब हैं। मैं एक उदाहरण बनाने की कोशिश करूंगा:

मान लें कि आपके पास एक सरल सीआरयूडी फॉर्म है। इस सहेजें बटन का कोड है:

var Client = PopulateDTO(); //put all the values in the controls, to an object 

if(Action==Actions.Create){ 
    _repository.Create(Client); 
} 
else if(Action==Actions.Update){ 
    _repository.Update(Client); 
} 
else if(Action==Actions.Delete){ 
    _repository.Delete(Client); 
} 

this.Close(); 

इस कोड काम करता है, लेकिन यह बुरा कोड, और पढ़ने के लिए मुश्किल है।के बहुरूपता (और रणनीति पैटर्न) का उपयोग करते हैं:

public abstract class BaseStrategy{ 
    abstract void Do(ClientDto Client); 
} 

public class CreateStrategy:BaseStrategy{ 
    public override void Do(ClientDto Client){ 
    _repo.Save(Client); 
    } 
} 

public class UpdateStrategy:BaseStrategy{ 
    public override void Do(ClientDto Client){ 
    _repo.Update(Client); 
    } 
} 

public class DeleteStrategy:BaseStrategy{ 
    public override void Do(ClientDto Client){ 
    _repo.Delete(Client); 
    } 
} 

तो, हम एक अमूर्त वर्ग, और 3 कार्यान्वयन, ग्राहक ऑब्जेक्ट वाले कुछ एक कर दिया है। अब, के रूप में बचाने के लिए बटन के कोड होगा:

BaseStrategy stg = GetCorrectStrategy(); 

var Client = PopulateDTO(); 

stg.Do(Client); 

this.close; 

और विधि GetCorrectStrategy() सही रणनीति कार्यान्वयन का दृष्टांत होगा, उपयोगकर्ता पैदा कर रही है, संपादन या ग्राहक को हटाने अगर निर्भर करता है।

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

0

चूंकि कई लोगों ने पहले से ही बहुरूपता के अच्छे उदाहरण दिए हैं, मैं एक अलग परिप्रेक्ष्य प्रदान करूंगा वास्तव में मुझे इसे ग्रोक करने में मदद की।

कार्यात्मक प्रोग्रामिंग में, कार्य ओओपी के विपरीत पहली कक्षा अवधारणाएं हैं जहां वस्तुएं सर्वोच्च हैं।

पॉलिमॉर्फिज्म ओओपी है कि एफपी के लिए कौन सा पैटर्न मिलान है। यहां एक ऐसा फ़ंक्शन है जो पैटर्न मिलान का उपयोग करता है (एमएल स्टाइल सिंटैक्स का उपयोग करके)।

let f x = 
     match x with 
     | T -> //do stuff with a T to return some value 
     | S -> //do stuff with an S to return some value 
     | U -> //do stuff with a U to return some value 
     | V -> //do stuff with a V to return some value 

तो जब आप समारोह च का उपयोग करें, आप इसे किसी भी प्रकार टी, एस, यू, या वी में दृढ़ता से एफपी भाषाओं टाइप किया एफ # की तरह की एक वस्तु पारित कर सकते हैं, एक्स के प्रकार T|S|U|V निरूपित किया जाता है। इस तरह के प्रकार आमतौर पर Sum प्रकार या टैग किए गए यूनियन के रूप में जाना जाता है।

यदि हम Human को एक अमूर्त वर्ग बनाने के लिए अपना उदाहरण ठीक करते हैं, तो यह स्पष्ट हो जाएगा कि ओओपी में बहुरूपता आपको एक योग प्रकार को व्यक्त करने का एक तरीका देती है।

इस प्रकार, CleanTheRoom एक ऐसा कार्य है जो Human टाइप करता है। लेकिन Human सिर्फ Man|Woman|Child के लिए नाम है जो एक योग प्रकार है। सी # जैसी भाषाओं और एफ # जैसी कार्यात्मक भाषाओं के बीच बड़ा अंतर यह है कि कोई वस्तु शीर्ष स्तर की चीजों के रूप में व्यवहार करता है जबकि अन्य व्यवहार शीर्ष स्तर की चीजों के रूप में कार्य करता है। इसके अलावा, सीओ # जैसी ओओपी भाषाओं में सब कुछ नाम होना चाहिए। एक कार्यात्मक भाषा में हम स्पष्ट रूप से नाम देने के बिना Man|Woman|Child प्रकार को इंगित कर सकते हैं।

कुंजी अलग CleanTheRoom तरीकों होने के रूप में कोड के बारे में सोचना है, बल्कि CleanTheRoom एक के रूप में विधि है कि एक प्रकार Man|Woman|Child (जो Human नाम है) लेता है के बारे में सोच नहीं है। पॉलिमॉर्फिज्म सिर्फ कार्यान्वयन विस्तार है।

संक्षेप में, बहुरूपता (विशेष रूप से सार कक्षाओं के साथ) मूल रूप से आपको केवल योग प्रकारों का नाम देने और पैटर्न मिलान करने का एक तरीका प्रदान करते हैं।

देखें:

0

सी # में एक उदाहरण:

यह मेरी कक्षा फ़ाइल है

class parent 
    { 
     public virtual string saySomething(string s) 
     { 
      return s+":Parent"; 
     } 
    } 
    class man : parent 
    { 
     public override string saySomething(string s) 
     { 
      return s+":Man"; 
     } 
    } 
    class woman : parent 
    { 
     public override string saySomething(string s) 
     { 
      return s+":Woman"; 
     } 
    } 
    class child : parent 
    { 
     public override string saySomething(string s) 
     { 
      return s+":Child"; 
     } 
    } 

चार बटन और एक लेबल बनाएँ।

यहाँ एक सरल Form1

private void Form1_Load(object sender, EventArgs e) 
     { 
      p1= new parent();  

     } 

     private void button1_Click(object sender, EventArgs e) 
     {    
      label1.Text = p1.saySomething("I am parent!"); 
     } 

     private void button2_Click(object sender, EventArgs e) 
     { 
      p1 = new man(); 
      label1.Text = p1.saySomething("I am man!"); 
     } 

     private void button3_Click(object sender, EventArgs e) 
     { 
      p1 = new woman(); 
      label1.Text = p1.saySomething("I am woman!"); 
     } 

     private void button4_Click(object sender, EventArgs e) 
     { 
      p1 = new child(); 
      label1.Text = p1.saySomething("I am child!"); 
     } 

पर कार्यान्वयन यह रन-टाइम बहुरूपता है है? पी 1 एक वस्तु है। स्थिति (संदर्भ) के आधार पर, एक बटन क्लिक करें, यह कोड के विभिन्न टुकड़े को निष्पादित कर रहा है। तो, पी 1 क्लिक घटना के आधार पर अलग-अलग व्यवहार कर रहा है।

+0

यदि आप इस उदाहरण को तरफ देखते हैं तो यह बहुरूपता है। लेकिन यह उदाहरण वास्तव में बहुरूपता की शक्ति नहीं दिखाता है। –

0
class Program 
{ 
    static void Main(string[] args) 
    { 
     List<ICleanTheRoom> cleanerList = new List<ICleanTheRoom> 
      { 
       new Child(), 
       new Woman(), 
       new Man() 
      }; 
     foreach (var cleaner in cleanerList) 
     { 
      cleaner.CleanTheRoom(); 
     } 
    } 
} 

internal interface ICleanTheRoom 
{ 
    void CleanTheRoom(); 
} 

// No need for super type 

//class Human : ICleanTheRoom 
//{ 
// public virtual void CleanTheRoom() 
// { 
// } 
//} 


internal class Woman : ICleanTheRoom 
{ 
    public void CleanTheRoom() 
    { 
     throw new NotImplementedException(); 
    } 
} 

class Man: ICleanTheRoom 
{ 
    public void CleanTheRoom() 
    { 
     throw new NotImplementedException(); 
    } 
} 

class Child: ICleanTheRoom 
{ 
    public void CleanTheRoom() 
    { 
     throw new NotImplementedException(); 
    } 
}