TypeScript クラスの継承とポリモーフィズム

TypeScript はオブジェクト指向プログラミングの継承とポリモーフィズムの特性をサポートしています。

SVG 図:クラス継承の階層 背景 タイトル クラス継承の階層構造 親クラス Animal Animal(親クラス) 子クラスへの矢印 子クラス Dog Dog(子クラス) extends Animal 子クラス Cat Cat(子クラス) extends Animal インスタンスへの矢印 インスタンス Dogインスタンス Catインスタンス 右側の説明 継承の特性 • extends による継承 • super() の呼び出し • メソッドのオーバーライド • ポリモーフィズム • instanceof 矢印マーカー

クラスの継承

extends キーワードを使用して継承を実装します。

例

class Animal {
    name: string;

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

    speak(): void {
        console.log(this.name + " が音を出す");
    }
}

class Dog extends Animal {
    breed: string;

    constructor(name: string, breed: string) {
        super(name);  // 親クラスのコンストラクターを呼び出す
        this.breed = breed;
    }

    speak(): void {
        console.log(this.name + " ワンワン!");
    }
}

var dog = new Dog("旺财", "金毛");
dog.speak();

実行結果:

旺財 ワンワンワン!

super キーワード

super は親クラスのメソッドとコンストラクターを呼び出すために使用します。

例

class Shape {
    color: string;

    constructor(color: string) {
        this.color = color;
    }

    describe(): string {
        return "これは " + this.color + " の図形";
    }
}

class Circle extends Shape {
    radius: number;

    constructor(color: string, radius: number) {
        super(color);
        this.radius = radius;
    }

    // 親クラスのメソッドをオーバーライド
    describe(): string {
        // 親クラスのメソッドを呼び出して拡張
        return super.describe() + "、半径は " + this.radius;
    }

    area(): number {
        return Math.PI * this.radius * this.radius;
    }
}

var circle = new Circle("赤色", 5);
console.log(circle.describe());
console.log("面積: " + circle.area().toFixed(2));

実行結果:

这是一个 红色的图形,半径是 5
面积: 78.54

ポリモーフィズム

子クラスのインスタンスは親クラスの型に代入できます。

例

class Animal {
    name: string;
    constructor(name: string) { this.name = name; }
    speak(): void {
        console.log(this.name + " が音を出す");
    }
}

class Cat extends Animal {
    speak(): void {
        console.log(this.name + " ニャーニャー!");
    }
}

class Dog extends Animal {
    speak(): void {
        console.log(this.name + " ワンワン!");
    }
}

// ポリモーフィズム:配列に異なる子クラスのインスタンスを格納
var animals: Animal[] = [
    new Cat("小白"),
    new Dog("旺财"),
    new Animal("動物")
];

// 同じメソッドを呼び出しても、子クラスごとに異なる実装になる
for (var _i = 0, animals_1 = animals; _i < animals_1.length; _i++) {
    var animal = animals_1[_i];
    animal.speak();
}

実行結果:

小白 ニャーニャーニャー!
旺財 ワンワンワン!
動物 声を出す

instanceof チェック

instanceof を使用してインスタンスの型をチェックします。

例

class Rectangle {
    width: number;
    height: number;
    constructor(width: number, height: number) {
        this.width = width;
        this.height = height;
    }
    area(): number {
        return this.width * this.height;
    }
}

class Circle {
    radius: number;
    constructor(radius: number) {
        this.radius = radius;
    }
    area(): number {
        return Math.PI * this.radius ** 2;
    }
}

var shapes = [new Rectangle(4, 5), new Circle(3)];

for (var _i = 0, shapes_1 = shapes; _i < shapes_1.length; _i++) {
    var shape = shapes_1[_i];
    if (shape instanceof Rectangle) {
        console.log("長方形の面積: " + shape.area());
    } else if (shape instanceof Circle) {
        console.log("円の面積: " + shape.area().toFixed(2));
    }
}

実行結果:

矩形面积: 20
圆形面积: 28.27

protected メンバー

protected メンバーは子クラス内で参照可能です。

例

class Person {
    protected name: string;

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

class Employee extends Person {
    private department: string;

    constructor(name: string, department: string) {
        super(name);
        this.department = department;
    }

    public introduce(): string {
        // protected メンバーにアクセスできる
        return "私は " + this.name + "、" + this.department + " で働いています";
    }
}

var emp = new Employee("Alice", "技術部");
console.log(emp.introduce());

// console.log(emp.name); // エラー:protected は外部からアクセスできません

実行結果:

我是 Alice,在 技术部 工作

まとめ

  • 継承:extends キーワード
  • super:親クラスの呼び出し
  • ポリモーフィズム:同じインターフェース、異なる実装
  • protected:子クラスからアクセス可能
その他の拡張