codestory

Methoden in TypeScript

  1. Was ist die Methode?
  2. Reguläre Methode
  3. Statische Methode
  4. Abstrakte Methode
  5. Optionale Parameter
  6. Parameter mit Standardwerten
  7. Parameter mit Union-Datentyp
  8. Eine Methode überschreiben
  9. Method Overloading

1. Was ist die Methode?

In der Programmiersprache TypeScript ist eine Methode ein Codeblock, der innerhalb einer Klasse definiert und nur beim Aufruf ausgeführt wird. Methoden unterteilen eine große Aufgabe in kleine Teile und führen die spezifische Operation dieses Programms aus. Dieser Prozess erhöht die Wiederverwendbarkeit des Codes und verbessert den modularen Ansatz des Programms.
Grundsätzlich werden Methoden in 3 Typen unterteilt:
  • Reguläre Methode (nicht statisch und nicht abstrakt)
  • Statische Methode.
  • Abstrakte Methode.

2. Reguläre Methode

Die Syntax zum Definieren einer regulären Methode:
[private | protected | public] method_name(arguments) : return_type {  
     // statement(s)  
}
  • return_type: Der Rückgabedatentyp der Methode. Verwenden Sie das Schlüsselwort void als Rückgabetyp, wenn die Methode nichts zurückgibt.
  • method_name: Der Methodenname. Im Gegensatz zu anderen Sprachen wie Java erlaubt TypeScript nicht zwei Methoden mit demselben Namen, auch wenn sie unterschiedliche Parameter haben. Dies ist notwendig, um Code TypeScript in Javascript umwandeln zu können.
  • arguments: Die Parameter von Methode
Beispiel: Die Klasse Cat und ihre Methode sayHello(..). Um Methode sayHello(..) aufzurufen, müssen Sie ein Objekt Cat erstellen und die Methode in Punktnotation aufrufen.
method_ex1.ts
class Cat {
    sayHello(name: string): void {
        console.log(`Hello ${name}`);
    }
}
function method_ex1_test() {
    var tom: Cat = new Cat(); // Create a Cat object.
    tom.sayHello("Jerry"); // Call the method through the object.
}
// Call the method:
method_ex1_test();
Output:
Hello Jerry
Eine Methode kann 0, 1 oder mehr Parameter enthalten, die durch Kommas getrennt sind.
method_ex2.ts
class Rectangle {
    width: number;
    height: number;

    constructor(width: number, height: number) {
        this.width = width;
        this.height = height;
    }
    getArea(): number {
        return this.width * this.height;
    }
    changeWidthHeight(newWidth: number, newHeight: number): void {
        this.width = newWidth;
        this.height = newHeight;
    }
    showMe(): void {
        console.log(`I am a rectangle, width: ${this.width}, height: ${this.height}`);
    }
}
function method_ex2_test() {
    var rec = new Rectangle(5, 10); // Create an object.

    rec.showMe();  // Call the method.
    var area = rec.getArea();  // Call the method.
    console.log(`Area: ${area}`);

    console.log(` --- Change width and height --- `);
    rec.changeWidthHeight(25, 15); // Set newWidth, newHeight

    rec.showMe(); // Call the method.  
    area = rec.getArea(); // Call the method.
    console.log(`Area: ${area}`);
}
method_ex2_test(); // Call the function.
Output:
I am a rectangle, width: 5, height: 10
Area: 50
 --- Change width and height ---
I am a rectangle, width: 25, height: 15
Area: 375

3. Statische Methode

TypeScript verwendet das Schlüsselwort static in Verbindung mit der regulären Methodendefinitionssyntax, um eine statische Methode zu definieren.
Die Syntax:
[private | protected | public] static method_name(arguments) : return_type {  
     // statement(s)  
}
Die Eigenschaften statischer Methoden:
  • Die statische Methode wird über den Klassennamen und die Punktnotation aufgerufen. Zum Beispiel MyUtility.sum(100, 50).
  • Nicht statische Mitglieder einer Klasse können nicht in einer statischen Methode erscheinen, es sei denn, auf sie wird über das Objekt zugegriffen (sehen Sie das Beispiel unten).
method_static_ex1.ts
class MyUtility {
    static sum(a: number, b: number): number { // same as 'public'
        return a + b;
    }
    public static minus(a: number, b: number): number {
        return a - b;
    }
}
function method_static_ex1_test() {
    var result = MyUtility.sum(100, 50);
    console.log(`Sum Result: ${result}`);

    result = MyUtility.minus(100, 50);
    console.log(`Minus Result: ${result}`);
}
method_static_ex1_test(); // Call the method
Output:
Sum Result: 150
Minus Result: 50
Betrachten Sie als Nächstes das folgende Beispiel:
  • side1, side2 und side3 sind nicht statische Felder der Triangle-Klasse, sie können nicht in der statischen Methode erscheinen.
method_static_ex2.ts
class Triangle {
    side1: number; side2: number; side3: number;// Non-static fields (Cann't use in static method)
    static DEFAULT_COLOR:string = 'blue'; // Static field (Can use in static method)

    constructor(s1: number, s2: number, s3: number) {
        var valid = Triangle.isValidSides(s1, s2, s3); // Check if all sides are valid.
        if (!valid) {
            throw new Error('Invalid Sides!'); // Throw an Error.
        }
        this.side1 = s1;
        this.side2 = s2;
        this.side3 = s3;
    }
    static isValidSides(s1: number, s2: number, s3: number): boolean {
        if (s1 < 0 || s2 < 0 || s3 < 0) {
            return false;
        }
        return s1 + s2 > s3 && s1 + s3 > s2 && s2 + s3 > s1;
    }
    isEquilateralTriangle(): boolean {
        return this.side1 == this.side2 && this.side2 == this.side3;
    }
}
function method_static_ex2_test() {
    var valid = Triangle.isValidSides(6, 8, 10);
    console.log(`Are sides 6, 8 and 10 valid to make a triangle? ${valid}`);

    var triangle = new Triangle(3.0, 4.0, 5.0);
    // Check if the triangle is equilateral triangle.
    var check = triangle.isEquilateralTriangle();
    console.log(`Is Equilateral Triangle? ${check}`);
}
method_static_ex2_test(); // Call the method.
Output:
Are sides 6, 8 and 10 valid to make a triangle? true
Is Equilateral Triangle? false

4. Abstrakte Methode

In der Sprache TypeScript ist eine abstrakte Methode eine nicht statische Methode und hat keinen Inhalt.
[protected | public] abstract method_name(arguments) : return_type;
Eine Klasse mit mindestens einer abstrakten Methode muss als abstrakt deklariert werden, und eine ihrer Unterklassen muss diese abstrakten Methoden überschreiben und Inhalte für sie schreiben.
method_abstract_ex1.ts
abstract class Person {
    abstract sayHello(): void; // An abstract method.
}
class EnglishPerson extends Person {
    sayHello(): void {
        console.log("Hello");
    }
}
class RussianPerson extends Person {
    sayHello(): void {
        console.log("Привет");
    }
}
function method_abstract_ex1_test() {
    var enPerson = new EnglishPerson();
    enPerson.sayHello();

    var ruPerson = new RussianPerson();
    ruPerson.sayHello();
}
method_abstract_ex1_test(); // Call the function.
Output:
Hello
Привет
  • TypeScript Classes

5. Optionale Parameter

Wie oben erwähnt, erlauben Klassen in TypeScript und JavaScript keine Methoden mit demselben Namen, aber eine Methode kann optionale Parameter enthalten.
Die Syntax:
// Non-static method with optional arguments:
[private | protected | public] method_name(args, optional_args?): return_type {  
     // statement(s)  
}

// Static method with optional arguments:
[private | protected | public] static method_name(args, optional_args?) : return_type {  
     // statement(s)  
}

// Abstract method with optional arguments:
[protected | public] abstract method_name(args, optional_args?): return_type;
Zum Beispiel:
method_optional_args_ex1.js
class MyUtils {
    static concat(s1: string, s2: string, s3?: string): string {
        if (s3) {
            return s1 + s2 + s3;
        }
        return s1 + s2;
    }
    static sum(v1: number, v2: number, v3?: number, v4?: number): number {
        return v1 + v2 + (v3 ?? 0) + (v4 ?? 0);
    }
}
function method_optional_args_ex1_test() {
    var result1 = MyUtils.concat('One', 'Two');
    console.log(`result1: ${result1}`);

    var result2 = MyUtils.concat('One', 'Two', 'Three');
    console.log(`result2: ${result2}`);

    var value1 = MyUtils.sum(1, 2, 3, 4);
    console.log(`value1: ${value1}`);

    var value2 = MyUtils.sum(1, 2, 3);
    console.log(`value2: ${value2}`);

    var value3 = MyUtils.sum(1, 2);
    console.log(`value3: ${value3}`);
}
method_optional_args_ex1_test(); // Call the method.
Output:
result1: OneTwo
result2: OneTwoThree
value1: 10
value2: 6
value3: 3

6. Parameter mit Standardwerten

TypeScript unterstützt Methoden mit Parametern mit Standardwerten, die die letzten Parameter in der Parameterliste sein müssen.
Die Syntax:
// Non-static method
[private | protected | public ] method_name (
             arg1 : data_type1, arg2 : data_type2,
             arg3 : data_type3 = defaultValue3,
             arg4 : data_type4 = defaultValue4) : return_type {
    // statement(s)  
}
// Static method
[private | protected | public ] static method_name (
             arg1 : data_type1, arg2 : data_type2,
             arg3 : data_type3 = defaultValue3,
             arg4 : data_type4 = defaultValue4) : return_type {
   // statement(s)  
}
// Abstract method
[protected | public ] abstract method_name (
             arg1 : data_type1, arg2 : data_type2,
             arg3 : data_type3 = defaultValue3,
             arg4 : data_type4 = defaultValue4) : return_type;
Zum Beispiel:
method_default_value_args_ex1.ts
class SalesUtils {
    static applyDiscount(amount : number, discount: number = 0.05)  : number {
        return amount * (1 - discount);
    }
}
function method_default_value_args_ex1_test() {
    var value1 = SalesUtils.applyDiscount(1000);
    console.log(`value1 = ${value1}`);

    var value2 = SalesUtils.applyDiscount(1000, 0.5);
    console.log(`value2 = ${value2}`);
}
method_default_value_args_ex1_test(); // Call the method.
Output:
value1 = 950
value2 = 500

7. Parameter mit Union-Datentyp

Der Parameter in einer Methode kann auch mit einem Union-Datentyp deklariert werden.
// Non-static method
[private | protected | public ] method_name (
             arg1 : data_type1, arg2 : data_type2,
             arg3 : data_type31 | data_type32 | data_type3N, // Union Data Type
             arg4 : data_type4 = defaultValue4) : return_type {
    //  Statament(s)
}
// Static method
[private | protected | public ] static method_name (
             arg1 : data_type1, arg2 : data_type2,
             arg3 : data_type31 | data_type32 | data_type3N, // Union Data Type
             arg4 : data_type4) : return_type {
    //  Statament(s)  
}
// Abstract method
[protected | public ] abstract method_name (
             arg1 : data_type1, arg2 : data_type2,
             arg3 : data_type31 | data_type32 | data_type3N, // Union Data Type
             arg4 : data_type4) : return_type;
Zum Beispiel:
method_union_type_args_ex1.ts
interface IStudent {
    studentId: number,
    studentName: string
}
interface IWorker {
    workerId: number,
    workerName: string
}
class AppUtils {
    static getName(person: IStudent | IWorker): string { // Union Type Arg
        var p = person as IStudent;
        if (p.studentName) {
            return p.studentName;
        }
        return (person as IWorker).workerName;
    }
}
function method_union_type_args_ex1_test() {
    var student = { studentId: 1, studentName: "Tom" };
    var worker = { workerId: 2, workerName: "Jerry" };

    var name1 = AppUtils.getName(student);
    var name2 = AppUtils.getName(worker);
    console.log(`name1: ${name1}`);
    console.log(`name2: ${name2}`);
}
method_union_type_args_ex1_test(); // Call the method.
Output:
name1: Tom
name2: Jerry

8. Eine Methode überschreiben

Eine Unterklasse kann eine Methode der Elternklasse überschreiben, wenn die folgenden Bedingungen erfüllt sind:
  • Die beiden Methoden müssen denselben Namen und dieselben Parameter haben.
  • Der Rückgabetyp der beiden Methoden muss gleich sein, oder der Rückgabetyp der Methode in der Unterklasse muss ein Untertyp des Rückgabetyps der Methode in der Elternklasse sein.

Zum Beispiel
  • Die Mouse-Klasse überschreibt die sayAnything()-Methode der Animal-Klasse.
method_override_ex1.ts
class Animal {
    sayAnything(): void {
        console.log('<Nothing>');
    }
}
class Mouse extends Animal {
    sayAnything(): void { // Override method of parent class.
        console.log('Hi Tom!');
    }
}
function method_override_ex1_test() {
    var animal = new Mouse();
    animal.sayAnything(); // Hi Tom!
}
method_override_ex1_test(); // Call the function.
Output:
Hi Tom!
Beispiel: Sie können auch das Schlüsselwort super verwenden, um eine Methode mit demselben Namen wie die Elternklasse aufzurufen.
method_override_ex2.ts
class BoldFormatter {
    formatText(text: string): string {
        return '<b>' + text + '</b>';
    }
}
class BoldItalicFormatter extends BoldFormatter {
    formatText(text: string): string { // Override method of parent class.
        var boldText = super.formatText(text); // Call super method.
        return '<i>' + boldText + '</i>';
    }
}
function method_override_ex2_test() {
    var formatter = new BoldItalicFormatter();
    var formattedText = formatter.formatText('Hello');
    console.log(formattedText);
}
method_override_ex2_test(); // Call the method.
Output:
<i><b>Hello</b></i>

9. Method Overloading

Im Artikel über Funktionen in TypeScript habe ich "Function Overloading" vorgestellt. Die Methode wird als Funktion der Klasse betrachtet, hat also auch ein ähnliches Konzept, nämlich "Method Overloading"
TypeScript lässt zwei Methoden mit demselben Namen in einer Klasse nicht zu, selbst wenn sie unterschiedliche Parameter haben. Mit Method Overloading können Sie eine Methode mit verschiedenen Parametertypen definieren.
In TypeScript sieht das Method Overloading anders aus als in C++, Java oder C#. Die Hauptidee beim Überladen von Methoden besteht darin, eine generische Methode zu erstellen, die überprüft, welcher Parametertyp beim Aufrufen der Methode übergeben wurde, und dann eine Logik für den entsprechenden Fall auszuführen. Es ist nützlich, Definitionen für die Methode hinzuzufügen, um anderen Programmierern zu helfen, sie richtig zu verwenden.
Die Syntax:
// Definition 1
[static] method_name(arg_11 : type_11, arg_1N : type_1N): return_type;
]// Definition 2
[static] method_name(arg_21 : type_21, arg_22 : type_22, arg_2M : type_2M) : return_type;
[static] method_name(... args : any[]) : return_type {
   // Method body.
}
Zum Beispiel:
method_overloading_ex1.ts
interface IDimension {
    width: number,
    height: number
}
class MathUtils {
    static getArea(dimension: IDimension): number; // Definition 1
    static getArea(width: number): number; // Definition 2
    static getArea(width: number, height: number): number; // Definition 3
    static getArea(...args: any[]): number {
        if (args.length == 1) {
            if (typeof args[0] == 'number') { // Use Definition 2
                return args[0] * args[0];
            } else { // Use Definition 1
                var dim = args[0] as IDimension;
                return dim.width * dim.height;
            }
        } else if (args.length == 2) {
            return args[0] * args[1];
        } else {
            throw new Error('Arguments Invalid!');
        }
    }
}
function method_overloading_ex1_test() {
    var area1 = MathUtils.getArea({ width: 10, height: 20 }); // 200
    var area2 = MathUtils.getArea(10); // 100
    var area3 = MathUtils.getArea(10, 15); // 150

    console.log(`area1: ${area1}`);
    console.log(`area2: ${area2}`);
    console.log(`area3: ${area3}`);
}
method_overloading_ex1_test(); // Call the function.
Output:
area1: 200
area2: 100
area3: 150