चलो पहले शुद्ध पैरामीट्रिक बहुरूपता के बारे में बात करते हैं और बाद में बंधे बहुरूपता में प्रवेश करते हैं।
पैरामीट्रिक बहुरूपता का क्या अर्थ है? ठीक है, इसका मतलब है कि एक प्रकार, या बल्कि प्रकार के निर्माता को एक प्रकार से पैरामीटर किया जाता है। चूंकि प्रकार एक पैरामीटर के रूप में पारित किया गया है, आप पहले से नहीं जान सकते कि यह क्या हो सकता है। आप इसके आधार पर कोई धारणा नहीं बना सकते। अब, यदि आप नहीं जानते कि यह क्या हो सकता है, तो इसका क्या उपयोग है? तुम्हारे द्वारा इससे क्या किया जा सकता है?
उदाहरण के लिए, आप इसे स्टोर और पुनः प्राप्त कर सकते हैं। यह मामला है जो आपने पहले ही उल्लेख किया है: संग्रह। किसी सूची या सरणी में किसी आइटम को संग्रहीत करने के लिए, मुझे आइटम के बारे में कुछ भी जानने की आवश्यकता नहीं है। सूची या सरणी पूरी तरह से प्रकार से अनजान हो सकती है।
लेकिन Maybe
प्रकार के बारे में क्या ? यदि आप इससे परिचित नहीं हैं, Maybe
तो एक प्रकार है जिसका शायद मूल्य है और शायद नहीं। आप इसका उपयोग कहां करेंगे? ठीक है, उदाहरण के लिए, जब किसी आइटम को एक शब्दकोश से बाहर निकाला जा रहा है: तथ्य यह है कि एक आइटम शब्दकोश में नहीं हो सकता है एक असाधारण स्थिति नहीं है, इसलिए यदि आइटम नहीं है, तो आपको वास्तव में एक अपवाद नहीं फेंकना चाहिए। इसके बजाय, आप एक उपप्रकार की एक आवृत्ति लौटाते हैं Maybe<T>
, जिसमें ठीक दो उपप्रकार होते हैं: None
और Some<T>
। int.Parse
किसी चीज़ का एक और उम्मीदवार जो वास्तव में Maybe<int>
एक अपवाद या पूरे int.TryParse(out bla)
नृत्य को फेंकने के बजाय वापस लौटना चाहिए ।
अब, आप तर्क कर सकते हैं कि Maybe
एक सूची की तरह थोड़े-थोड़े हैं जो केवल शून्य या एक तत्व हो सकते हैं। और इस प्रकार थोरा-संग्रह एक संग्रह।
फिर किस बारे में Task<T>
? यह एक प्रकार है जो भविष्य में किसी बिंदु पर एक मूल्य वापस करने का वादा करता है, लेकिन जरूरी नहीं कि अभी एक मूल्य हो।
या किस बारे में Func<T, …>
? यदि आप प्रकारों पर अमूर्त नहीं कर सकते हैं, तो आप एक प्रकार से दूसरे प्रकार के फ़ंक्शन की अवधारणा का प्रतिनिधित्व कैसे करेंगे?
या, आम तौर पर: यह मानते हुए कि अमूर्त और पुन: उपयोग सॉफ्टवेयर इंजीनियरिंग के दो मौलिक संचालन हैं, आप प्रकारों पर अमूर्त करने में सक्षम क्यों नहीं होना चाहेंगे?
तो, चलिए अब बंधे हुए बहुरूपता के बारे में बात करते हैं। बंधे हुए बहुरूपता मूल रूप से जहां पैरामीट्रिक बहुरूपता और उपप्रकार बहुरूपता मिलते हैं: एक प्रकार के निर्माता के बजाय इसके प्रकार के पैरामीटर के बारे में पूरी तरह से विचलित होने के कारण, आप कुछ निर्दिष्ट प्रकार का उपप्रकार बांधने (या विवश) कर सकते हैं ।
आइए संग्रह पर वापस जाएं। एक हैशटेबल लें। हमने ऊपर कहा है कि सूची में इसके तत्वों के बारे में कुछ भी जानने की आवश्यकता नहीं है। खैर, एक हैशटेबल करता है: यह जानना आवश्यक है कि यह उन्हें हैश कर सकता है। (नोट: C # में, सभी ऑब्जेक्ट्स हैज़ेबल हैं, जैसे सभी ऑब्जेक्ट्स की समानता के लिए तुलना की जा सकती है। यह सभी भाषाओं के लिए सही नहीं है, हालांकि, और कभी-कभी C # में भी डिज़ाइन की गलती मानी जाती है।)
इसलिए, आप अपने प्रकार के पैरामीटर को हैशटेबल में प्रमुख प्रकार के लिए कसना चाहते हैं IHashable
:
class HashTable<K, V> where K : IHashable
{
Maybe<V> Get(K key);
bool Add(K key, V value);
}
कल्पना करें कि इसके बजाय आपके पास यह था:
class HashTable
{
object Get(IHashable key);
bool Add(IHashable key, object value);
}
value
वहाँ से बाहर निकलने के साथ आप क्या करेंगे ? आप इसके साथ कुछ नहीं कर सकते, आप केवल यह जानते हैं कि यह एक वस्तु है। और यदि आप इस पर पुनरावृत्ति करते हैं, तो आप सभी प्राप्त करते हैं IHashable
जो आपको पता है कि एक जोड़ी है जो एक है (जो आपको बहुत मदद नहीं करता है क्योंकि इसमें केवल एक ही संपत्ति है Hash
) और कुछ आप जानते हैं कि यह एक है object
(जो आपको और भी कम मदद करता है)।
या आपके उदाहरण के आधार पर कुछ:
class Repository<T> where T : ISerializable
{
T Get(int id);
void Save(T obj);
void Delete(T obj);
}
आइटम को क्रमबद्ध करने की आवश्यकता है क्योंकि यह डिस्क पर संग्रहीत होने जा रहा है। लेकिन अगर आपके पास इसके बजाय क्या है:
class Repository
{
ISerializable Get(int id);
void Save(ISerializable obj);
void Delete(ISerializable obj);
}
सामान्य मामले के साथ, यदि आप एक डाल BankAccount
में, आप एक पाने के BankAccount
लिए वापस, तरीके और गुण की तरह साथ Owner
, AccountNumber
, Balance
, Deposit
, Withdraw
, आदि कुछ आप के साथ काम कर सकते हैं। अब, अन्य मामला? तुम एक में डाल दिया BankAccount
लेकिन तुम वापस एक मिल Serializable
जो सिर्फ एक संपत्ति है,: AsString
। तुम क्या करने जा रहे हो?
कुछ साफ-सुथरी चालें भी हैं जो आप बंधे हुए बहुरूपता के साथ कर सकते हैं:
एफ-बाउंडेड परिमाणीकरण मूल रूप से है जहां प्रकार चर बाधा में फिर से दिखाई देता है। यह कुछ परिस्थितियों में उपयोगी हो सकता है। उदाहरण के लिए आप एक ICloneable
इंटरफ़ेस कैसे लिखते हैं ? आप एक विधि कैसे लिखते हैं जहां रिटर्न प्रकार कार्यान्वयन वर्ग का प्रकार है? MyType सुविधा वाली भाषा में, यह आसान है:
interface ICloneable
{
public this Clone(); // syntax I invented for a MyType feature
}
बंधी हुई बहुरूपता वाली भाषा में, आप इसके बजाय कुछ ऐसा कर सकते हैं:
interface ICloneable<T> where T : ICloneable<T>
{
public T Clone();
}
class Foo : ICloneable<Foo>
{
public Foo Clone()
{
// …
}
}
ध्यान दें कि यह MyType संस्करण जितना सुरक्षित नहीं है, क्योंकि टाइप करने वाले के लिए "गलत" वर्ग को पास करने से कोई रोक नहीं सकता है:
class EvilBar : ICloneable<SomethingTotallyUnrelatedToBar>
{
public SomethingTotallyUnrelatedToBar Clone()
{
// …
}
}
सार प्रकार सदस्य
जैसा कि यह पता चला है, यदि आपके पास अमूर्त प्रकार के सदस्य हैं और उप-योग हैं, तो आप वास्तव में पैरामीट्रिक बहुरूपता के बिना पूरी तरह से प्राप्त कर सकते हैं और अभी भी सभी समान चीजें कर सकते हैं। स्काला इस दिशा में अग्रसर है, पहली प्रमुख भाषा होने के नाते जो जेनेरिक के साथ शुरू हुई थी और फिर उन्हें हटाने की कोशिश की जा रही थी, जो कि वास्तव में जावा और सी # के आसपास का दूसरा तरीका है।
मूल रूप से, स्काला में, जैसे आपके पास सदस्य के रूप में फ़ील्ड और गुण और विधियाँ हो सकती हैं, आपके पास भी प्रकार हो सकते हैं। और जैसे खेतों और संपत्तियों और तरीकों को बाद में एक उपवर्ग में लागू करने के लिए अमूर्त छोड़ा जा सकता है, प्रकार के सदस्यों को भी सार छोड़ दिया जा सकता है। आइए संग्रह पर वापस जाएं, एक सरल List
, जो कुछ इस तरह दिखाई देगा, अगर यह C # में समर्थित हो:
class List
{
T; // syntax I invented for an abstract type member
T Get(int index) { /* … */ }
void Add(T obj) { /* … */ }
}
class IntList : List
{
T = int;
}
// this is equivalent to saying `List<int>` with generics
interface IFoo<T> where T : IFoo<T>
भी याद आया । यह स्पष्ट रूप से वास्तविक जीवन का अनुप्रयोग है। उदाहरण बहुत अच्छा है। लेकिन किसी कारण से मैं संतुष्ट महसूस नहीं कर रहा हूँ। मैं इसके बजाय अपने मन को प्राप्त करना चाहता हूं जब यह उचित है और जब यह नहीं है। यहाँ जवाबों का इस प्रक्रिया में कुछ योगदान है, लेकिन मैं अभी भी इस सब के आसपास खुद को अधूरा महसूस कर रहा हूं। यह अजीब है क्योंकि भाषा-स्तर की समस्याएं मुझे बहुत पहले से परेशान नहीं करती हैं।