TypeScript: наследование классов и полиморфизм
TypeScript поддерживает возможности наследования и полиморфизма объектно-ориентированного программирования.
SVG-диаграмма: иерархия наследования классовНаследование классов
Используйте ключевое слово extends для реализации наследования.
Пример
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
speak(): void {
console.log(this.name + " make a sound");
}
}
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();
name: string;
constructor(name: string) {
this.name = name;
}
speak(): void {
console.log(this.name + " make a sound");
}
}
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();
Вывод:
Wangcai woof woof woof!
ключевое слово 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("red", 5);
console.log(circle.describe());
console.log("Площадь: " + circle.area().toFixed(2));
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("red", 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 + " make a sound");
}
}
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("Xiaobai"),
new Dog("Wangcai"),
new Animal("Животные")
];
// Вызов одного и того же метода; у разных подклассов разные реализации
for (var _i = 0, animals_1 = animals; _i < animals_1.length; _i++) {
var animal = animals_1[_i];
animal.speak();
}
name: string;
constructor(name: string) { this.name = name; }
speak(): void {
console.log(this.name + " make a sound");
}
}
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("Xiaobai"),
new Dog("Wangcai"),
new Animal("Животные")
];
// Вызов одного и того же метода; у разных подклассов разные реализации
for (var _i = 0, animals_1 = animals; _i < animals_1.length; _i++) {
var animal = animals_1[_i];
animal.speak();
}
Вывод:
Xiaobai meow meow meow! Wangcai woof woof woof! Animals make sounds.
Проверка 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));
}
}
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-члены
Защищённые члены видны в подклассах.
Пример
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 + " working";
}
}
var emp = new Employee("Alice", "Technology Department");
console.log(emp.introduce());
// console.log(emp.name); // Ошибка: protected недоступен извне
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 + " working";
}
}
var emp = new Employee("Alice", "Technology Department");
console.log(emp.introduce());
// console.log(emp.name); // Ошибка: protected недоступен извне
Вывод:
我是 Alice,在 技术部 工作
Итог
- Наследование:ключевое слово extends
- super:Вызов родительского класса
- Полиморфизм:Один интерфейс, разные реализации
- protected:Виден в подклассах