JavaRush /Курсы /Модуль 2: Fullstack /Наследование классов

Наследование классов

Модуль 2: Fullstack
5 уровень , 6 лекция
Открыта

7.1 Основы наследования

Наследование — один из ключевых принципов объектно-ориентированного программирования (ООП), который позволяет создавать новые классы на основе уже существующих. В TypeScript наследование помогает организовать иерархию классов, что упрощает повторное использование кода, уменьшает дублирование и улучшает читаемость.

В TypeScript наследование позволяет одному классу (производному или дочернему классу) наследовать свойства и методы другого класса (базового или родительского класса). Это достигается с помощью ключевого слова extends.

Синтаксис наследования

Для создания производного класса, который наследует свойства и методы базового класса, используется следующий синтаксис:

    
      class BaseClass {
        // Свойства и методы базового класса
      }

      class DerivedClass extends BaseClass {
        // Свойства и методы производного класса
      }
    
  

Примеры наследования

Рассмотрим пример с базовым классом Animal и производным классом Dog:

JavaScript
    
      "use strict";
      class Animal {
          constructor(name) {
              this.name = name;
          }
          move(distance) {
              console.log(`${this.name} moved ${distance} meters.`);
          }
      }
      class Dog extends Animal {
          bark() {
              console.log('Woof! Woof!');
          }
      }
      let dog = new Dog('Rex');
      dog.bark(); // Вывод: Woof! Woof!
      dog.move(10); // Вывод: Rex moved 10 meters.
    
  
TypeScript
    
      class Animal {
        name: string;

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

        move(distance: number): void {
          console.log(`${this.name} moved ${distance} meters.`);
        }
      }

      class Dog extends Animal {
        bark(): void {
          console.log('Woof! Woof!');
        }
      }

      let dog = new Dog('Rex');
      dog.bark(); // Вывод: Woof! Woof!
      dog.move(10); // Вывод: Rex moved 10 meters.
    
  

Здесь класс Dog наследует свойства и методы класса Animal. Экземпляр класса Dog может использовать как метод bark, так и метод move, унаследованный от класса Animal.

7.2 Конструкторы в наследуемых классах

Производные классы могут иметь свои собственные конструкторы. В этом случае необходимо вызвать конструктор базового класса с помощью ключевого слова super.

Синтаксис использования super

Ключевое слово super используется для вызова конструктора и методов базового класса из производного класса.

Пример:

JavaScript
    
      "use strict";
      class Animal {
          constructor(name) {
              this.name = name;
          }
          move(distance) {
              console.log(`${this.name} moved ${distance} meters.`);
          }
      }
      class Bird extends Animal {
          constructor(name, wingSpan) {
              super(name); // Вызов конструктора базового класса
              this.wingSpan = wingSpan;
          }
          fly(distance) {
              console.log(`${this.name} with wingspan of ${this.wingSpan} meters flew ${distance} meters.`);
          }
      }
      let bird = new Bird('Eagle', 2);
      bird.fly(100); // Вывод: Eagle with wingspan of 2 meters flew 100 meters.
      bird.move(20); // Вывод: Eagle moved 20 meters.
    
  
TypeScript
    
      class Animal {
        name: string;

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

        move(distance: number): void {
          console.log(`${this.name} moved ${distance} meters.`);
        }
      }

      class Bird extends Animal {
        wingSpan: number;

        constructor(name: string, wingSpan: number) {
          super(name); // Вызов конструктора базового класса
          this.wingSpan = wingSpan;
        }

        fly(distance: number): void {
          console.log(`${this.name} with wingspan of ${this.wingSpan} meters flew ${distance} meters.`);
        }
      }

      let bird = new Bird('Eagle', 2);
      bird.fly(100); // Вывод: Eagle with wingspan of 2 meters flew 100 meters.
      bird.move(20); // Вывод: Eagle moved 20 meters.
    
  

Здесь у класса Bird есть собственный конструктор, который вызывает конструктор базового класса Animal с помощью super(name). Также добавляется новое свойство wingSpan и метод fly.

7.3 Переопределение методов

Производные классы могут переопределять методы базового класса для предоставления новой реализации. Для этого используется тот же синтаксис, что и при объявлении метода в базовом классе.

JavaScript
    
      "use strict";
      class Animal {
        constructor(name) {
          this.name = name;
        }
        makeSound() {
          console.log('Some generic animal sound');
        }
      }
      class Cat extends Animal {
        constructor(name) {
          super(name);
        }
        makeSound() {
          console.log('Meow! Meow!');
        }
      }
      let animal = new Animal('Generic Animal');
      animal.makeSound(); // Вывод: Some generic animal sound
      let cat = new Cat('Whiskers');
      cat.makeSound(); // Вывод: Meow! Meow!
    
  
TypeScript
    
      class Animal {
        name: string;

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

        makeSound(): void {
          console.log('Some generic animal sound');
        }
      }

      class Cat extends Animal {
        constructor(name: string) {
          super(name);
        }

        makeSound(): void {
          console.log('Meow! Meow!');
        }
      }

      let animal = new Animal('Generic Animal');
      animal.makeSound(); // Вывод: Some generic animal sound

      let cat = new Cat('Whiskers');
      cat.makeSound(); // Вывод: Meow! Meow!
    
  

В этом примере метод makeSound класса Cat переопределяет метод makeSound класса Animal, предоставляя собственную реализацию.

7.4 Доступ к методам базового класса

Производные классы могут вызывать методы базового класса с помощью ключевого слова super.

Пример:

JavaScript
    
      "use strict";
      class Animal {
          constructor(name) {
              this.name = name;
          }
          makeSound() {
              console.log('Some generic animal sound');
          }
      }
      class Dog extends Animal {
          constructor(name) {
              super(name);
          }
          makeSound() {
              super.makeSound(); // Вызов метода базового класса
              console.log('Woof! Woof!');
          }
      }
      let dog = new Dog('Rex');
      dog.makeSound();
      // Вывод:
      // Some generic animal sound
      // Woof! Woof!
    
  
TypeScript
    
      class Animal {
        name: string;

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

        makeSound(): void {
          console.log('Some generic animal sound');
        }
      }

      class Dog extends Animal {
        constructor(name: string) {
          super(name);
        }

        makeSound(): void {
          super.makeSound(); // Вызов метода базового класса
          console.log('Woof! Woof!');
        }
      }

      let dog = new Dog('Rex');
      dog.makeSound();
      // Вывод:
      // Some generic animal sound
      // Woof! Woof!
    
  

Здесь метод makeSound класса Dog вызывает метод makeSound базового класса Animal с помощью super.makeSound(), а затем выполняет собственную логику.

7.5 Примеры

Наследование активно используется в реальных проектах для моделирования иерархий объектов и их взаимодействий. Рассмотрим несколько примеров.

Пример 1: Система управления персоналом

JavaScript
    
      "use strict";
      class Employee {
          constructor(name, position) {
              this.name = name;
              this.position = position;
          }
          work() {
              console.log(`${this.name} is working as a ${this.position}.`);
          }
      }
      class Manager extends Employee {
          constructor(name, department) {
              super(name, 'Manager');
              this.department = department;
          }
          work() {
              super.work();
              console.log(`${this.name} is managing the ${this.department} department.`);
          }
      }
      let manager = new Manager('Alice', 'Sales');
      manager.work();
      // Вывод:
      // Alice is working as a Manager.
      // Alice is managing the Sales department.
    
  
TypeScript
    
      class Employee {
        name: string;
        position: string;

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

        work(): void {
          console.log(`${this.name} is working as a ${this.position}.`);
        }
      }

      class Manager extends Employee {
        department: string;

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

        work(): void {
          super.work();
          console.log(`${this.name} is managing the ${this.department} department.`);
        }
      }

      let manager = new Manager('Alice', 'Sales');
      manager.work();
      // Вывод:
      // Alice is working as a Manager.
      // Alice is managing the Sales department.
    
  

Здесь класс Manager наследует от класса Employee и переопределяет метод work, добавляя дополнительное поведение.

Пример 2: Моделирование транспортных средств

JavaScript
    
      "use strict";
      class Vehicle {
          constructor(make, model) {
              this.make = make;
              this.model = model;
          }
          move() {
              console.log(`The ${this.make} ${this.model} is moving.`);
          }
      }
      class Car extends Vehicle {
          constructor(make, model, numDoors) {
              super(make, model);
              this.numDoors = numDoors;
          }
          move() {
              super.move();
              console.log(`The car has ${this.numDoors} doors.`);
          }
      }
      let car = new Car('Toyota', 'Camry', 4);
      car.move();
      // Вывод:
      // The Toyota Camry is moving.
      // The car has 4 doors.
    
  
TypeScript
    
      class Vehicle {
        make: string;
        model: string;

        constructor(make: string, model: string) {
          this.make = make;
          this.model = model;
        }

        move(): void {
          console.log(`The ${this.make} ${this.model} is moving.`);
        }
      }

      class Car extends Vehicle {
        numDoors: number;

        constructor(make: string, model: string, numDoors: number) {
          super(make, model);
          this.numDoors = numDoors;
        }

        move(): void {
          super.move();
          console.log(`The car has ${this.numDoors} doors.`);
        }
      }

      let car = new Car('Toyota', 'Camry', 4);
      car.move();
      // Вывод:
      // The Toyota Camry is moving.
      // The car has 4 doors.
    
  

Здесь класс Car наследует от класса Vehicle и переопределяет метод move, добавляя дополнительную информацию о количестве дверей.

Преимущества наследования

  1. Повторное использование кода: наследование позволяет повторно использовать код базового класса, избегая дублирования и упрощая сопровождение.
  2. Расширяемость: производные классы могут добавлять новые свойства и методы или переопределять существующие, что упрощает расширение функциональности.
  3. Структурированность: наследование помогает организовать код в логически связанные иерархии, улучшая его читаемость и поддержку.
3
Задача
Модуль 2: Fullstack, 5 уровень, 6 лекция
Недоступна
Наследование свойств и методов
Наследование свойств и методов
3
Задача
Модуль 2: Fullstack, 5 уровень, 6 лекция
Недоступна
super для доступа к методам базового класса
super для доступа к методам базового класса
3
Задача
Модуль 2: Fullstack, 5 уровень, 6 лекция
Недоступна
Переопределение конструктора
Переопределение конструктора
3
Задача
Модуль 2: Fullstack, 5 уровень, 6 лекция
Недоступна
Расширение функциональности
Расширение функциональности
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ