टाइपस्क्रिप्ट में 'एक्सटेंड्स' और 'इम्प्लीमेंट्स' के बीच क्या अंतर है


126

मैं जानना चाहूंगा कि आदमी और बच्चे में क्या समानता है और वे कैसे भिन्न हैं।

class Person {
  name: string;
  age: number;
}
class child extends Person {}
class man implements Person {}

1
अच्छी तरह से यहाँ समझाया, stackoverflow.com/a/35990799/452213 । विशेष रूप से, उदाहरण: typecriptlang.org/play/…
sudip

जवाबों:


154

लघु संस्करण

  • extends माध्यम:

नया वर्ग एक बच्चा है । यह विरासत के साथ आने वाले लाभ प्राप्त करता है। इसके माता-पिता के रूप में सभी गुण, विधियां हैं। यह इनमें से कुछ को ओवरराइड कर सकता है और नए को लागू कर सकता है, लेकिन मूल सामग्री पहले से ही शामिल है।

  • implements माध्यम:

नया वर्ग के रूप में इलाज किया जा सकता एक ही "आकार" जबकि, यह एक बच्चे को नहीं है । इसे किसी भी तरीके से पारित किया जा सकता है Person, जहां आवश्यकता होती है, चाहे अलग-अलग अभिभावक होंPerson

अधिक ...

में OOP (C #, जावा जैसी भाषाओं) हम प्रयोग करेंगे

extendsलाभ से लाभ (देखें विकि )। छोटा हवाला:

... अधिकांश वर्ग-आधारित वस्तु-उन्मुख भाषाओं में निहितता एक तंत्र है जिसमें एक वस्तु मूल वस्तु के सभी गुणों और व्यवहारों को प्राप्त करती है। वंशानुक्रम प्रोग्रामर को अनुमति देता है: ऐसी कक्षाएं बनाएं जो मौजूदा कक्षाओं में निर्मित हों ...

implementsबहुरूपता के लिए अधिक होगा ( विकी देखें )। छोटा हवाला:

... बहुरूपता विभिन्न प्रकारों की संस्थाओं को एकल इंटरफ़ेस का प्रावधान है ...

तो, हम वास्तव में हमारे अलग वंशानुक्रम के पेड़ हो सकते हैं class Man

class Man extends Human ...

लेकिन अगर हम यह भी घोषित करते हैं कि हम एक अलग प्रकार का दिखावा कर सकते हैं - Person:

class Man extends Human 
          implements Person ...

.. तो हम इसे कहीं भी उपयोग कर सकते हैं, जहां Personआवश्यक है। हमें बस व्यक्तियों को पूरा करना है "interface" (अर्थात इसके सभी सार्वजनिक सामानों को लागू करना है)

implementअन्य वर्ग? यह वास्तव में अच्छा सामान है

जावास्क्रिप्ट का अच्छा चेहरा (लाभों में से एक) डक टाइपिंग ( देखें विकि ) का अंतर्निहित समर्थन है । छोटा हवाला:

"अगर यह एक बतख की तरह चलता है और यह बतख की तरह झुकता है, तो इसे बतख होना चाहिए।"

तो, जावास्क्रिप्ट में, अगर दो अलग-अलग वस्तुओं ... एक समान विधि (जैसे render()) वे एक समारोह में पारित किया जा सकता है जो यह उम्मीद करता है:

function(engine){
  engine.render() // any type implementing render() can be passed
}

ऐसा न करने के लिए - हम टाइपस्क्रिप्ट में एक ही कर सकते हैं - अधिक टाइप किए गए समर्थन के साथ। और वह जहां है

class implements class

इसकी भूमिका है, जहां यह समझ में आता है

OOP भाषाओं में C#... ऐसा करने का कोई तरीका नहीं है ...

इसके अलावा प्रलेखन को यहाँ मदद करनी चाहिए:

इंटरफेसेस फैली हुई कक्षाएं

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

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

class Control {
    private state: any;
}

interface SelectableControl extends Control {
    select(): void;
}

class Button extends Control implements SelectableControl {
    select() { }
}

class TextBox extends Control {
    select() { }
}

// Error: Property 'state' is missing in type 'Image'.
class Image implements SelectableControl {
    private state: any;
    select() { }
}

class Location {

}

इसलिए जबकि

  • extends इसका मतलब है - यह अपने माता-पिता से प्राप्त करता है
  • implementsइस मामले में लगभग एक इंटरफ़ेस को लागू करने जैसा है। चाइल्ड ऑब्जेक्ट यह दिखावा कर सकता है कि यह माता-पिता है ... लेकिन इसे कोई कार्यान्वयन नहीं मिलता है

जब आप कहते हैं, " extendsयह अपने माता-पिता से मिलता है", तो क्या यह निजी सदस्यों पर लागू होता है? मिसाल के तौर पर class Person {private name: string} class man extends Person{gender: string;}करता है manसंपत्ति नाम नहीं है?
davejoem

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

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

इसके अलावा, मुझे एक और बिंदु मिला। यदि यह विस्तार की परिभाषा है। तो कृपया अगर आप इस stackoverflow.com/questions/60390454/…
kushalvm

98

टाइपस्क्रिप्ट (और कुछ अन्य ओओ भाषा) में आपके पास कक्षाएं और इंटरफेस हैं।

एक इंटरफ़ेस का कोई कार्यान्वयन नहीं है, यह इस प्रकार के सदस्यों / विधि का सिर्फ एक "अनुबंध" है।
उदाहरण के लिए:

interface Point {
    x: number;
    y: number;
    distance(other: Point): number;
}

इस Pointइंटरफ़ेस को लागू करने वाले उदाहरणों में दो प्रकार के सदस्य होने चाहिए: xऔर y, और एक विधि distanceजो एक और Pointउदाहरण प्राप्त करती है और एक रिटर्न देती है number
इंटरफ़ेस उन में से किसी को भी लागू नहीं करता है।

कक्षाएं कार्यान्वयन हैं:

class PointImplementation implements Point {
    public x: number;
    public y: number;

    constructor(x: number, y: number) {
        this.x = x;
        this.y = y;
    }

    public distance(other: Point): number {
        return Math.sqrt(Math.pow(this.x - other.x, 2) + Math.pow(this.y - other.y, 2));
    }
}

( खेल के मैदान में कोड )

अपने उदाहरण में आप अपनी Personकक्षा को एक बार एक वर्ग के रूप में मानते हैं जब आप इसे बढ़ाते हैं और एक बार जब आप इसे लागू करते हैं तो एक इंटरफ़ेस के रूप में।
तुम्हारा कोड:

class Person {
    name: string;
    age: number;
}
class Child  extends Person {}

class Man implements Person {}

एक संकलन त्रुटि कह रही है:

क्लास 'मैन' गलत तरीके से इंटरफ़ेस 'पर्सन' को लागू करता है।
प्रॉपर्टी 'नाम' टाइप में गायब है 'मैन'।

और ऐसा इसलिए है क्योंकि इंटरफेस में कार्यान्वयन की कमी है।
इसलिए यदि आप implementएक वर्ग हैं तो आप केवल कार्यान्वयन के बिना ही इसका "अनुबंध" लेते हैं, इसलिए आपको यह करने की आवश्यकता होगी:

class NoErrorMan implements Person {
    name: string;
    age: number;
}

( खेल के मैदान में कोड )

लब्बोलुआब यह है कि ज्यादातर मामलों में आप extendदूसरी कक्षा में जाना चाहते हैं और इसके लिए implementनहीं।


7
यह उत्तर समझने में सरल है।
अक्षय राऊत

6

@ निट्ज-टॉमर से बढ़िया जवाब! मेरी बहुत मदद की ... मैंने उसका डेमो थोड़ा बढ़ाया:

IPoint interface;
Point implements IPoint;
Point3D extends Point;

और वे किस IPointप्रकार के कार्यों की अपेक्षा करते हैं ।

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

यहाँ विस्तारित डेमो


यह प्रश्न का उत्तर प्रदान नहीं करता है। किसी लेखक से स्पष्टीकरण मांगने या उसका अनुरोध करने के लिए, उनके पोस्ट के नीचे एक टिप्पणी छोड़ दें। - समीक्षा से
aronisstav

1
@aronisstav मैंने केवल एक विस्तृत डेमो पोस्ट किया था जो मुझे एक अच्छा उत्तर मिला जिसने पहले से ही मेरी मदद की। लेकिन हो सकता है कि कोई और काम मुझे मिल जाए, जो मैंने डेमो को उपयोगी बनाने के लिए किया। बस इतना ही। टिप्पणियाँ वास्तव में एक कोड-ब्लॉक डालने के लिए नहीं होती हैं, इसलिए मुझे उत्तर-पोस्ट में यह बेहतर समझ में आता है। तो इसमें दिक्कत क्या है?
andzep

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

@andzep आपका विस्तारित डेमो उदाहरण वास्तव में मददगार है।
namit

3
  1. इंटरफ़ेस आकार के साथ इंटरफ़ेस का विस्तार करता है
  2. इंटरफ़ेस आकार के साथ कक्षा का विस्तार करता है
  3. क्लास इम्प्लीमेंट इंटरफ़ेस को इंटरफ़ेस द्वारा प्रदान किए गए सभी क्षेत्रों को लागू करना चाहिए
  4. कक्षा के आकार के साथ वर्ग को लागू करता है
  5. कक्षा सभी क्षेत्रों के साथ वर्ग का विस्तार करती है

extendsविरासत पर ध्यान केंद्रित करें और implementsबाधा पर ध्यान केंद्रित करें कि क्या इंटरफेस या कक्षाएं।


0

वी.एस. लागू करता है

  • extends: बच्चे वर्ग (जो विस्तारित है) होगा वारिस सभी गुण और विधियों में से किसी वर्ग फैली हुई होती है
  • implements: वह वर्ग जो implementsकीवर्ड का उपयोग करता है, उसे उस वर्ग के सभी गुणों और विधियों को लागू करने की आवश्यकता होगी जो वह करता हैimplements

सरल शब्दों में कहें:

  • extends: यहाँ आपको मूल वर्ग से ये सभी विधियाँ / गुण मिलते हैं, इसलिए आपको इसे स्वयं लागू करने की आवश्यकता नहीं है
  • implements: यहां एक अनुबंध है जिसका वर्ग को पालन करना है। वर्ग को कम से कम निम्नलिखित विधियों / गुणों को लागू करना होगा

उदाहरण:

class Person {
  name: string;
  age: number;

  walk(): void {
    console.log('Walking (person Class)')
  }

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}
class child extends Person { }

// Man has to implements at least all the properties
// and methods of the Person class
class man implements Person {
  name: string;
  age: number

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  walk(): void {
    console.log('Walking (man class)')
  }

}

(new child('Mike', 12)).walk();
// logs: Walking(person Class)

(new man('Tom', 12)).walk();
// logs: Walking(man class)

उदाहरण में हम देख सकते हैं कि बच्चा वर्ग व्यक्ति से सब कुछ प्राप्त करता है, जबकि पुरुष वर्ग को व्यक्तिगत रूप से सब कुछ लागू करना पड़ता है।

अगर हम उदाहरण के लिए चलने की विधि के लिए मैन क्लास से कुछ निकालते हैं तो हमें निम्नलिखित संकलन समय त्रुटि मिलेगी :

वर्ग 'आदमी' गलत तरीके से कक्षा 'व्यक्ति' को लागू करता है। क्या आपका मतलब 'व्यक्ति' का विस्तार करना और उसके सदस्यों को उपवर्ग के रूप में विरासत में देना था? संपत्ति 'चलना' प्रकार 'आदमी' में गायब है, लेकिन टाइप 'व्यक्ति' में आवश्यक है। (2720)

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