2016-11-14 13 views
15

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

इंटरफेस के साथ पूरा बिंदु व्यवहार का पर्दाफाश करना है। एक वर्ग ने कहा व्यवहार के एक स्पष्ट कार्यान्वयन के द्वारा इसे लागू करता है।

उस स्थिति में, हालांकि इंटरफेस गुण हो सकते हैं, अधिकांश समय हम व्यवहार संबंधी मुद्दों के कारण इंटरफेस की परवाह करते हैं। तो अधिकांश प्रकार, इंटरफेस केवल व्यवहार के अनुबंध हैं।

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

एक ट्यूटोरियल में मैं इस देखा:

export interface User { 
    name: string; // required with minimum 5 chracters 
    address?: { 
     street?: string; // required 
     postcode?: string; 
    } 
} 

लेकिन एक मिनट प्रतीक्षा करें। क्यों User एक इंटरफेस है? अगर हमें लगता है कि सी #, User एक इंटरफ़ेस नहीं होना चाहिए। सच में, इसे देखते हुए, ऐसा लगता है कि हम व्यवहार के अनुबंध के बजाय डेटा प्रकार User को परिभाषित कर रहे हैं।

में सोच रही थी जैसे हम सी # में करते हैं, स्वाभाविक बात यह होगा:

export class User { 
    public name: string; 
    public address: Address; 
} 
export class Address { 
    public street: string; 
    public postcode: string; 
} 

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

तो टाइपस्क्रिप्ट में किस इंटरफेस का अर्थ है? लोग टाइपस्क्रिप्ट में इंटरफेस का उपयोग क्यों करते हैं जैसे कि हम सी # में क्लिक्स का उपयोग करते हैं? टाइपस्क्रिप्ट में इंटरफ़ेस का सही ढंग से उपयोग कैसे किया जाना चाहिए: व्यवहार के अनुबंध स्थापित करने के लिए, या गुणों को परिभाषित करने और वस्तु के पास होना चाहिए?

+3

सी # से बहुत कम टाइपस्क्रिप्ट पर लागू होता है क्योंकि बाद वाला [संरचनात्मक रूप से टाइप किया गया] (https://www.typescriptlang.org/docs/handbook/type-compatibility.html) है। साथ ही, कुछ गुणों को पूरी तरह से व्यवहार माना जा सकता है :-) – artem

+0

मुझे नहीं पता कि आप किस प्रकार के उत्तर की उम्मीद कर रहे हैं। आप इस तरह की भाषाओं की तुलना नहीं कर सकते हैं। – nozzleman

+2

मुझे विश्वास है कि सी # उद्धृत करने में गलती थी। मैं भाषाओं की तुलना नहीं करना चाहता, न ही इस तरह के कुछ भी। मैंने बस इंटरफ़ेस के उपयोग के उदाहरण के रूप में सी # के बारे में बात की थी जिसका उपयोग मैं करता हूं। मैं बस इतना जानना चाहता हूं कि टाइपस्क्रिप्ट में इंटरफेस या कक्षाओं का उपयोग कब करना चाहिए, क्योंकि लोग उनमें से प्रत्येक के लिए एक विशिष्ट उद्देश्य रखने के बजाय, दोनों एक ही उद्देश्य के लिए उनका उपयोग करते हैं। जैसा कि मैंने कहा, वही कक्षाओं और इंटरफेस दोनों का उपयोग करके ऊपर पूरा किया जा सकता है, और मैंने लोगों को दोनों तरीकों से बाहर कर दिया है, जो मुझे भ्रमित करता है। सवाल है * बस टाइपस्क्रिप्ट * के बारे में, सी # सिर्फ एक उदाहरण था। – user1620696

उत्तर

22

पर विचार करें कि जावास्क्रिप्ट में, डेटा अक्सर सादे वस्तुओं के रूप में, अक्सर JSON के माध्यम से आदान-प्रदान किया जाता है:

let data = JSON.parse(someString); 

मान लीजिए कि इस dataUser ऑब्जेक्ट की श्रृंखला है, और हम इसे एक समारोह को पारित करेंगे:

data.forEach(user => foo(user)) 

foo इस तरह टाइप किया जा जाएगा:

function foo(user: User) { ... } 

लेकिन प्रतीक्षा करें, हमने किसी भी समय new User नहीं किया! क्या हमें? क्या हमें User और map सभी data पर लिखना होगा, भले ही परिणाम वास्तव में वही होगा, Object गुणों के साथ? नहीं, यह सिर्फ सिस्टम सिस्टम को संतुष्ट करने के लिए पागलपन होगा, लेकिन रनटाइम के बारे में कुछ भी नहीं बदलेगा। एक साधारण interface जो वर्णन करता है कि विशिष्ट ऑब्जेक्ट की तरह दिखने की अपेक्षा की जाती है ("व्यवहार" करने के लिए) यहां पूरी तरह से पर्याप्त है।

+2

और हाँ, 'data.forEach (foo)' ... मैं स्पष्टता के लिए केवल लंबे समय से उपयोग कर रहा हूं। : ओ) – deceze

+0

"यह टाइप सिस्टम को संतुष्ट करने के लिए सिर्फ पागलपन होगा, लेकिन रनटाइम के बारे में कुछ भी नहीं बदलेगा।" - इस लाइन ने मेरे लिए अंतर बनाया, धन्यवाद :) और ... क्या मैं कहने में सही हूं, इतनी सारी प्रणाली अंतर्निहित जावास्क्रिप्ट की गतिशीलता को खो देगी? – asolvent

+1

@ASolvent कि गतिशीलता एक डबल तलवार वाली तलवार है ... साधारण इंटरफेस के साथ बतख टाइपिंग ऑब्जेक्ट्स बहुत बढ़िया है, लेकिन संदर्भ द्वारा सरल प्रकारों का निहित कास्टिंग एक गड़बड़ी हो सकता है। आप एक सुखद माध्यम खोजना चाहते हैं: जरूरी प्रकार के नाखूनों को जहां आवश्यक हो, बतख प्रकार जहां पर्याप्त हो। – deceze

1

केवल मूल deserialization तंत्र का उपयोग, आप एक विशिष्ट वर्ग के एक उदाहरण deserialize नहीं कर सकते हैं। आप केवल एक सादे-पुराने-जावास्क्रिप्ट-ऑब्जेक्ट में deserialize कर सकते हैं।ऐसी वस्तुएं टाइपस्क्रिप्ट इंटरफेस का पालन कर सकती हैं लेकिन कक्षा का उदाहरण नहीं हो सकती हैं। यदि आपको डेटा से निपटने की आवश्यकता है जो एक serialization सीमा पार करता है जैसे कि webservice से अपेक्षित डेटा, इंटरफेस का उपयोग करें। यदि आपको अपने मूल्यों के नए उदाहरण उत्पन्न करने की आवश्यकता है, तो बस उन्हें शाब्दिक रूप से बनाएं या एक सुविधा फ़ंक्शन बनाएं जो उन्हें वापस लाए - ऑब्जेक्ट्स जो उस इंटरफ़ेस का पालन करते हैं।

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

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

टाइपप्रति में
9

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

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

let user: User = { 
    name: 'abc', 
    address: { 
    street: 'xyz', 
    }, 
}; 

या आप एक इंटरफेस के लिए किसी भी डेटा ऑब्जेक्ट (उदा JSON पार्स के माध्यम से प्राप्त) आवंटित (लेकिन अपने पूर्व के चेक पर जोर देना चाहिए कि यह वास्तव में मान्य डेटा है) कर सकते हैं। इसलिए डेटा के लिए इंटरफेस बहुत लचीला हैं।

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

अंगूठे का मेरा व्यक्तिगत नियम:

  • अगर मैं (स्रोतों बदलती के) मैं इंटरफेस का उपयोग शुद्ध डेटा के साथ काम कर रहा हूँ
  • मैं कुछ जो एक पहचान और राज्य है मॉडलिंग कर रहा हूँ (और शायद राज्य को संशोधित करने के लिए संलग्न तरीकों) मैं एक वर्ग का उपयोग कर रहा हूँ।
+0

अच्छा जवाब, विशेष रूप से अंगूठे का आपका नियम। उन्हें काफी मदद मिली। धन्यवाद! – ntaso

+0

अच्छा जवाब - अंत में छोड़कर आप "और संभवतः विधियों" कहते हैं - लेकिन यदि आप JSON.stringify() के माध्यम से एपीआई को डेटा भेजने के लिए ऐसी कक्षा का उपयोग करते हैं तो आप एक खाली ऑब्जेक्ट {} के साथ समाप्त हो जाएंगे क्योंकि यह नहीं है पता है कि उन तरीकों से क्या करना है। @JasonKleban से नीचे जवाब देखें – rmcsharry

10

मैं भी सी # पृष्ठभूमि से टाइपस्क्रिप्ट पर आया और वही चीजें सोच लीं। मैं पीओसीओ की लाइनों के साथ सोच रहा था (क्या पोटो एक चीज है?)

तो टाइपस्क्रिप्ट में कौन से इंटरफेस का मतलब है?

The Typescript Handbook कहना है कि इंटरफेस "को परिभाषित करने के ठेके अपने कोड के भीतर" के लिए हैं लगता है।

लोग टाइपस्क्रिप्ट में इंटरफेस का उपयोग क्यों करते हैं जैसे हम सी # में कक्षाओं का उपयोग करते हैं?

मैं यहां @ धोखे के उत्तर से सहमत हूं।

जॉन पापा अपने blog पर कक्षाओं और इंटरफेस के विषय पर फैलता है। उन्होंने सुझाव दिया कि कक्षाएं विरासत, [और] सिंगलटन ऑब्जेक्ट्स "का उपयोग करके कई नए उदाहरण बनाने के लिए सबसे उपयुक्त हैं। इसलिए, टाइपस्क्रिप्ट हैंडबुक और एक व्यक्ति की राय में वर्णित टाइपस्क्रिप्ट इंटरफेस के इरादे के आधार पर, ऐसा लगता है कि टाइपस्क्रिप्ट में अनुबंध स्थापित करने के लिए कक्षाएं आवश्यक नहीं हैं। इसके बजाय, आपको इंटरफेस का उपयोग करना चाहिए। (आपकी सी # इंद्रियां अभी भी नाराज होंगी।)

टाइपस्क्रिप्ट में इंटरफ़ेस का सही ढंग से उपयोग किया जाना चाहिए: व्यवहार के अनुबंध स्थापित करने के लिए, या गुणों और वस्तु को परिभाषित करने के लिए?

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

इसके अलावा, मेरे सहकर्मी ने मुझे इंटरफेस के बजाय कक्षाओं का उपयोग करने के लिए मिला क्योंकि इंटरफेस कंपाइलर में कोई कोड नहीं बनाते हैं।

उदहारण:

यह टाइपप्रति:

class Car implements ICar { 
    foo: string; 
    bar(): void { 
    } 
} 

interface ICar { 
    foo: string; 
    bar(): void; 
} 

का उत्पादन इस Javascript:

var Car = (function() { 
    function Car() { 
    } 
    Car.prototype.bar = function() { 
    }; 
    return Car; 
}()); 

Try it out

2

कैसे इंटरफेस ठीक से टाइपप्रति में प्रयोग किया जाना चाहिए: अनुबंध स्थापित करने के लिए व्यवहार के, या गुणों और वस्तु को परिभाषित करने के लिए होना चाहिए?

टाइपस्क्रिप्ट में इंटरफ़ेस आकार ऑब्जेक्ट्स हैं, जो ऑब्जेक्ट की अपेक्षित संरचना का वर्णन करते हैं। यदि किसी मान में एक निश्चित इंटरफ़ेस एनोटेशन होता है, तो आप इंटरफ़ेस में परिभाषित सदस्यों की विशेषता वाले ऑब्जेक्ट होने की अपेक्षा करते हैं। सदस्य मूल्य या कार्य (विधियां) हो सकते हैं। आम तौर पर, उनका व्यवहार (कार्य निकाय) अनुबंध का हिस्सा नहीं है। लेकिन आप निर्दिष्ट कर सकते हैं कि वे readonly हैं या नहीं।

तो टाइपस्क्रिप्ट में कौन से इंटरफेस का मतलब है? लोग टाइपस्क्रिप्ट में इंटरफेस का उपयोग क्यों करते हैं जैसे कि हम सी # में क्लिक्स का उपयोग करते हैं?

टाइपस्क्रिप्ट इंटरफेस सी # इंटरफेस के समान भूमिका निभा सकते हैं यदि उन्हें टाइपस्क्रिप्ट कक्षाओं द्वारा लागू करने की अपेक्षा की जाती है।

लेकिन न केवल एक वर्ग एक इंटरफ़ेस को कार्यान्वित कर सकता है; कर सकते हैं मूल्य के किसी भी प्रकार:

{ 
    printHello:() => console.log("hello") 
} 

इस प्रकार हम

const o: HelloPrinter = { 
    printHello:() => console.log("hello") 
} 

और टाइपप्रति संकलक जीता कर सकते हैं ':

interface HelloPrinter { 
    printHello(): void 
} 

निम्नलिखित वस्तु एक वर्ग नहीं है, लेकिन फिर भी इंटरफ़ेस लागू करता है शिकायत नहीं करते।

ऑब्जेक्ट हमें कक्षा लिखने के लिए मजबूर किए बिना हमारे इंटरफ़ेस को लागू करता है।

इंटरफेस के साथ काम करना (इंटरफेस और) कक्षाओं के साथ काम करने से अधिक हल्का वजन है।

लेकिन यदि आपको रनटाइम के दौरान प्रकार का नाम (वर्ग/इंटरफ़ेस नाम) पता होना चाहिए तो कक्षाएं सही विकल्प हैं, क्योंकि इंटरफ़ेस नाम केवल संकलन समय पर ही ज्ञात हैं।