Vererbung und Polymorphismus in ECMAScript

1- Inheritance (die Erbschaft) im ECMAScript

Vor dem Lernen "Vererbung und Polymorphismus in ECMAScript" stellen Sie sicher dass Sie "Die Klasse und das Objekt" kenen. Wenn nicht, lernen Sie sie:
ECMAScript genehmigt Ihnen, eine ausgeweiterte Klasse aus einer oder vieler Klasse zu erstellen. Die Klasse wird derived class genannt, oder einfach die untergeordneten genannt.
Die untergeordnete Klasse wird die Property , die Methode und die anderen Mitglieder aus der Vater-Klasse erben. Sie kann die Methode aus der Vater-Klasse auch überschreiben (override). Im   ECMAScript hat jede Klasse nur einen einzigen constructor. Wenn eine Klasse ihre eigene Constructor nicht selbst definieret, wird sie den Constructor der Vater-Klasse geerbt. Umgekehrt, wenn die untergeordnete Klasse einen Constructor definiert, wird sie den Constructor der Vater-Klasse nicht geerbt.
Änders als  Java, CSharp und einige Sprache genehmigt ECMAScript die Multi-Inherit. Eine Klasse kann aus einer oder vieler Vaterklasse ausgeweitert werden.
Wir brauchen einige Klasse zur Teilnahme an dem Beispiel.
  • Animal: Die Klasse bezeichnet eine Klasse Animal (Tier).
  • Duck: Die Klasse bezeichnet die Klasse Ente ,eine untergeordnete Klasse von Animal.
  • Cat: Die Klasse bezeichnet die Klasse Katze, eine untergeordnete Klasse von Animal
  • MouseDie Klasse bezeichnet die Klasse Maus. eine untergeordnete Klasse von Animal.
Im  ECMAScript wird der constructor benutzt, ein Objekt zu erstellen und die Wert für die Property zuzuweisen. Der Constructor der untergeordneten Klasse ruft immer auf den Constructor der Vaterklasse auf, um die Wert für die property der Vaterklasse zuzuweisen, dann die Wert für ihre property zuzuweisen
Gucken Sie das Beispiel
Cat ist die untergeordnete Klasse, die aus der Klasse  Animal geerbt. Sie hat auch ihre eigene  property
inherit-example1.js
class Animal {

   constructor(name)  {
     this.name = name;
   }

   showInfo()  {
     console.log("I'm " + this.name);
   }

   move()  {
     console.log("Moving..");
   }

}

class Cat extends Animal {
    constructor(name, age, height) {
       super(name);
       // Cat's properties:
       this.age = age;
       this.height = height;
    }

    // Das Method , deren Name so gleich wie Vater-Klasse ist, überschreiben (override).
    showInfo()  {
      console.log("My name is " + this.name);
    }

    // Other method...
    sleep()  {
       console.log("Sleeping..");
    }
}

// ------------- TEST --------------------
let tom = new Cat("Tom", 3, 20);

console.log("Call move() method");

tom.move();

console.log("\n");
console.log("Call showInfo() method");

tom.showInfo();
Was passiert wenn Sie ein Objekt durch den constructor erstellen? Wie ruft es auf den constructor der Vaterklasse auf? Sehen Sie bitte das folgende Beispiel:
Im Illustrationsbild oben sehen Sie, dass der Constructor der Vaterklasse in den Constructor der untergeordneten Klasse aufgeruft wird. Er wird die Wert für die property der Vaterklasse zuweisen und dann die property der untergeordnete Klassen werden die Wert auch zugewiesen.

2- Das Method überschreiben

Standardmäßig wird die untergeordneten Klasse die Methode aus der Vaterklass geerbt, Allerdings kann die untergeordneten Klasse auf die Methode der Vaterklasse überschreiben (override)
.
inheritance-example2.js
class Animal {

   constructor(name)  {
     this.name = name;
   }

   showInfo()  {
     console.log("I'm " + this.name);
   }

   move()  {
     console.log("Moving..");
   }

}

class Mouse extends Animal {

    constructor(name, age, height) {
       super(name);

       this.age = age;
       this.height = height;
    }

    // das Method , deren Name so gleich wie Vater-Klasse ist, überschreiben (override).
    showInfo()  {
      // Das Method showInfo() der Vater-Klasse aufrufen.
      super.showInfo();
      console.log ("Age: " + this.age);
      console.log ("Height: " + this.height);
    }

    // das Method , deren Name so gleich wie Vater-Klasse ist, überschreiben (override).
    move()  {
      console.log("Mouse Moving..");
    }
}

// ------------- TEST --------------------
let jerry = new Mouse("Jerry", 3, 5);

console.log("Call move() method");

jerry.move();

console.log("\n");
console.log("Call showInfo() method");

jerry.showInfo();

3- Das abstrakte Method

Es gibt die Definition über eine abstraktet Methode oder eine abstrakte Klasse in der Sprache wie  Java, C#. Aber es ist nicht klar im  ECMAScript. Aber wir kann sie definieren
Eine abstrakte Klasse definiert die abstrakte Methode und die untergeordneten Klasse müssen diese Methode zur Benutzung überschreiben (override). Die abstrakten Methode werfen immer die Ausnahme "Not Implemented Error".
abstract-example.js
// An abstract class.
class AbstractDocument {

    constructor(name) {
        this.name = name
    }

    // A method can not be used, because it always throws an error.
    show() {
        // Not Implemented Error
        throw "Subclass must implement abstract method";
    }
}

class PDF extends AbstractDocument {

    // Override method of parent class
    show() {
        console.log("Show PDF document:", this.name);
    }
}



class Word extends AbstractDocument {
    show() {
        console.log("Show Word document:", this.name)
    }
}



// -------------------- TEST -------------------------
let doc1 = new PDF("Python tutorial");
let doc2 = new Word("Java IO Tutorial");
let doc3 = new PDF("ECMAScript Date & Time Tutorial");

let documents = [doc1, doc2, doc3];


for (let i = 0; i < documents.length; i++) {
    documents[i].show();
}

let doc4 = new AbstractDocument("An Abstract Document");

doc4.show(); // Throw Error!!!
Das oben Beispiel beschreibt die Polymorphie (Polymorphism) im  ECMAScript. Ein Objekt  Document (dokument) kann in vielen Formen ( PDF, Word, Excel, ...) bezeichnet werden.
Ein andere Beispeil über die Polymorphie: Wenn ich eine asiatische Person erwähne, ist das sehr abstrakt, das kann ein Japaner , ein Vietnameser oder ein Inder sein, ... Aber sie haben die typischen Merkmale der Asiate

4- Die Operator instanceof, typeof

instanceof

Die Operator  instanceof hilf Ihnen zu prüfen, ob "etwas" die Objekt einer Klasse ist oder nicht.
instanceof-example.js
class Person {

}

// A Child class of Person
class AsianPerson extends Person {

}

class Triangle {

}

let person = new Person();
let asianPerson = new AsianPerson();

let triangle = new Triangle();

let isPerson = person instanceof Person;
console.log( isPerson ); // true

console.log( asianPerson instanceof Person ); // true

console.log( person instanceof AsianPerson ); // false
console.log( triangle instanceof Person ); // false
console.log( triangle instanceof AsianPerson ); // false

typeof

Der Operator typeof wird benutzt um das Typ vom "etwas" zu prüfen. Das Ergebnis ist der Name des Typ.

Type Result
undefined "undefined"
null "object"
boolean "boolean"
number "number"
String "string"
Symbol (new in ECMAScript 6) "symbol"
Host object (provided by the JS environment) Implementation-dependent
Function object (implements [[Call]] in ECMA-262 terms) "function"
Any other object "object"
typeof-example.js
// A Class:
class Person {

}
// An Object:
let person = new Person();

console.log( typeof Person ); // function
console.log( typeof person ); // object

// null:
console.log( typeof null ); // object

// A Number:
let intValue = 100;

console.log( typeof intValue ); // number

// NaN (Not a Number)
console.log( typeof NaN); // number

// A String
let strValue = "Hello";

console.log( typeof strValue ); // string

// A Boolean:
let boolValue = true;

console.log( typeof boolValue ); // boolean

// undefined
console.log( typeof undefined); // undefined

// An Array
let years = [1980, 2003, 2018];

console.log( typeof years ); // object

// A Function
let myFunc = function()  {

}

console.log( typeof myFunc ); // function

// A Symbol
let mySymbol =   Symbol();

console.log( typeof mySymbol ); // symbol

Is Sub Class?

Angenommen, Sie haben 2 Klasse   A & B. Das folgende Beispiel hilft Sie zu prüfen, ob A die untergeordnete Klasse von B ist oder nicht.
let isChild = A === B || A.prototype instanceof B;
issubclass-example.js
class Animal {

}

class Cat extends Animal {
 
}

class AsianCat extends Cat {

}

// ------------- TEST --------------------

console.log("AsianCat === Animal? " + (AsianCat === Animal)); // false

let isSubClass1 = AsianCat === Animal || AsianCat.prototype instanceof Animal;

console.log("AsianCat is child of Animal? " + isSubClass1); // true

let isSubClass2 = AsianCat === Animal || Animal.prototype instanceof AsianCat;

console.log("Animal is child of AsianCat? " + isSubClass2); // false

 

5- Polymorphism mit der Funktion

Die Sprachen wie Java, C# sind sehr eng für dem Datentyp. Deshalb wenn Sie ein Method (Funktion) aufrufen, müssen Sie das rechte Datentyp, das dem Parameter entspricht, übergeben. Im ECMAScript wenn Sie eine Funktion aufrufen, können Sie in Parameter mit irgendeinem Datentyp übergeben. Die Risiken können passieren und der Programmer müssen diese Risiken selbst managen.
Hier erstelle ich 2 Klasse  English und  French. Diese Klasse haben 2 Methode greeting(). Die beide erstellen die unterschiedlichen Begrüßungswörte. Erstellung der 2 Objekten, die der 2 oben Klasse entsprechen und die Aufruf der Aktion von 2 Objekte in einer gleichen Funktion (die Funktion  intro)
polymorphism-example.js
class English {

    greeting() {
        console.log("Hello");
    }
}

class French {
    greeting() {
        console.log("Bonjour");
    }
}

function intro(language) {
    language.greeting();
}

// -------------- TEST ----------------------

let flora = new English();
let aalase = new French();

// Call function:
intro(flora);
intro(aalase);

let someObject = {};

intro(someObject);// Error!!!
Das Beispiel durchführen:
OK, die Kode des obengemeinten Beispiel ändern, in die notwendigen Prüfungen hinfügen um die Risiken für Ihre Applikation zu vermeiden:
polymorphism-example2.js
class English {

    greeting() {
        console.log("Hello");
    }
}

class French {
    greeting() {
        console.log("Bonjour");
    }
}

function intro(language) {
    // Check type of 'language' object.
    if(language instanceof English || language instanceof French)  {
      language.greeting();
    }
}

// -------------- TEST ----------------------

let flora = new English();
let aalase = new French();

// Call function:
intro(flora);
intro(aalase);

let someObject = {};

intro(someObject);
Die Anwendung der Architektur  "die Klasse & die Inheritance" hilft Ihrer Applikation bei dem mehr einfachen Management und der Vermeidung der Risiken.
polymorphism-example3.js
// A Base class
class Language {

}
class English extends Language {

    greeting() {
        console.log("Hello");
    }
}

class French  extends Language {
    greeting() {
        console.log("Bonjour");
    }
}

function intro(language) {
    // Check type of 'language' object.
    if(language instanceof Language)  {
      language.greeting();
    }
}

// -------------- TEST ----------------------

let flora = new English();
let aalase = new French();

// Call function:
intro(flora);
intro(aalase);

let someObject = {};

intro(someObject);
Mehr sehen: