Наследование
Наследование позволяет создать новый класс на основе существующего. Исходный класс называют родительским, а новый — наследником или дочерним. Наследник получает все свойства и методы родителя и может добавить свои или изменить унаследованные. Так общий код пишут один раз, а различия — в каждом наследнике.
extends
Класс-наследник объявляют словом extends:
class Animal {
constructor(name) {
this.name = name;
}
}
class Dog extends Animal {}
const dog = new Dog('Шарик');
console.log(dog.name); // ШарикУ Dog нет своего конструктора — он достался от Animal.
Свои методы
Наследник может добавить методы, которых нет у родителя. Унаследованные при этом остаются доступны:
class Animal {
constructor(name) {
this.name = name;
}
describe() {
return `${this.name} — животное`;
}
}
class Dog extends Animal {
bark() {
return `${this.name}: Гав!`;
}
}
const dog = new Dog('Шарик');
console.log(dog.describe()); // Шарик — животное
console.log(dog.bark()); // Шарик: Гав!super
Если наследнику нужен свой конструктор, первым делом в нём вызывают super() — конструктор родителя:
class Animal {
constructor(name) {
this.name = name;
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name);
this.breed = breed;
}
}
const dog = new Dog('Шарик', 'лайка');
console.log(dog.name, dog.breed); // Шарик лайкаПереопределение методов
Наследник может объявить метод с тем же именем — тогда будет вызываться его версия. Родительскую версию вызывают через super:
class Cat {
sound() {
return 'Мяу';
}
}
class Kitten extends Cat {
sound() {
return super.sound() + '-мяу';
}
}
console.log(new Kitten().sound()); // Мяу-мяуПроверка типа
Оператор instanceof проверяет, создан ли объект по классу. Объект наследника считается и объектом родителя:
class Animal {}
class Dog extends Animal {}
const dog = new Dog();
console.log(dog instanceof Dog); // true
console.log(dog instanceof Animal); // trueЧастая ошибка
В конструкторе наследника нельзя обращаться к this до вызова super() — получится ошибка ReferenceError:
class Animal {
constructor(name) {
this.name = name;
}
}
class Dog extends Animal {
constructor(name, breed) {
this.breed = breed;
super(name);
}
}
try {
new Dog('Шарик', 'лайка');
} catch (error) {
console.log(error.name); // ReferenceError
}Объект создаёт конструктор родителя, поэтому до super() его ещё нет. Сначала вызывают super(), и только потом добавляют свои свойства.