JavaRush /Курсы /Модуль 2: Fullstack /Абстрактные классы и методы

Абстрактные классы и методы

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

8.1 Абстрактные классы

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

Абстрактный класс — это класс, который нельзя непосредственно инстанцировать. Он используется для создания базовых классов, которые служат шаблонами для других классов. Абстрактные классы могут содержать как реализацию методов, так и абстрактные методы, которые нужно реализовать в производных классах.

Синтаксис объявления абстрактного класса

Абстрактный класс объявляется с использованием ключевого слова abstract.

Пример:

JavaScript
    
      "use strict";
      class Animal {
        constructor(name) {
          this.name = name;
        }
        move(distance) {
          console.log(`${this.name} moved ${distance} meters.`);
        }
      }
      // Класс-наследник, который реализует абстрактный метод makeSound
      class Dog extends Animal {
        constructor(name) {
          super(name);
        }
        makeSound() {
          console.log(`${this.name} says: Woof!`);
        }
      }
      // Создаем объект класса Dog и используем его методы
      const myDog = new Dog('Rex');
      myDog.makeSound(); // Вывод: Rex says: Woof!
      myDog.move(10); // Вывод: Rex moved 10 meters.
    
  
TypeScript
    
      abstract class Animal {
        name: string;

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

        abstract makeSound(): void; // Абстрактный метод

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

      // Класс-наследник, который реализует абстрактный метод makeSound
      class Dog extends Animal {
        constructor(name: string) {
          super(name);
        }

        makeSound(): void {
          console.log(`${this.name} says: Woof!`);
        }
      }

      // Создаем объект класса Dog и используем его методы
      const myDog = new Dog('Rex');
      myDog.makeSound(); // Вывод: Rex says: Woof!
      myDog.move(10);    // Вывод: Rex moved 10 meters.
    
  

Здесь класс Animal — абстрактный, и он содержит абстрактный метод makeSound, который нужно реализовать в производных классах. Также класс содержит метод move, который имеет реализацию.

Производные классы и реализация абстрактных методов

Производные классы, наследующие абстрактный класс, должны реализовать все его абстрактные методы. Если производный класс не реализует все абстрактные методы, его также нужно объявить как абстрактный.

Пример:

JavaScript
    
      "use strict";
      class Animal {
          constructor(name) {
              this.name = name;
          }
      }
      class Dog extends Animal {
          constructor(name) {
              super(name);
          }
          // Реализация абстрактных методов
          makeSound() {
              console.log('Woof! Woof!');
          }
          move(distance) {
              console.log(`${this.name} moved ${distance} meters.`);
          }
      }
      let dog = new Dog('Rex');
      dog.makeSound(); // Вывод: Woof! Woof!
      dog.move(10); // Вывод: Rex moved 10 meters.
    
  
TypeScript
    
      abstract class Animal {
        name: string;

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

        // Абстрактные методы, которые должны реализовать все производные классы
        abstract makeSound(): void;
        abstract move(distance: number): void;
      }

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

        // Реализация абстрактных методов
        makeSound(): void {
          console.log('Woof! Woof!');
        }

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

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

В этом примере класс Dog наследует абстрактный класс Animal и реализует метод makeSound.

8.2 Абстрактные методы

Абстрактные методы объявляются в абстрактных классах без реализации. Эти методы должны быть реализованы в производных классах. Или производный класс также нужно объявить абстрактным.

Синтаксис абстрактных методов

Абстрактные методы объявляются с использованием ключевого слова abstract и не содержат тела метода.

Пример:

JavaScript
    
      "use strict";
      class Shape {
          display() {
              console.log(`Area: ${this.calculateArea()}`);
          }
      }
      class Circle extends Shape {
          constructor(radius) {
              super();
              this.radius = radius;
          }
          calculateArea() {
              return Math.PI * this.radius * this.radius;
          }
      }
      let circle = new Circle(5);
      circle.display(); // Вывод: Area: 78.53981633974483
    
  
TypeScript
    
      abstract class Shape {
        abstract calculateArea(): number; // Абстрактный метод

        display(): void {
          console.log(`Area: ${this.calculateArea()}`);
        }
      }

      class Circle extends Shape {
        radius: number;

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

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

      let circle = new Circle(5);
      circle.display(); // Вывод: Area: 78.53981633974483
    
  

Здесь абстрактный метод calculateArea объявлен в абстрактном классе Shape и реализован в производном классе Circle.

8.3 Примеры

Абстрактные классы и методы широко используются для создания шаблонов классов, обеспечивающих общие интерфейсы и функциональность. Рассмотрим несколько примеров.

Пример 1: Иерархия транспортных средств

JavaScript
    
      "use strict";
      class Vehicle {
          constructor(make, model) {
              this.make = make;
              this.model = model;
          }
          move(distance) {
              console.log(`${this.make} ${this.model} moved ${distance} meters.`);
          }
      }
      class Car extends Vehicle {
          constructor(make, model) {
              super(make, model);
          }
          startEngine() {
              console.log(`The engine of ${this.make} ${this.model} is started.`);
          }
      }
      let car = new Car('Toyota', 'Camry');
      car.startEngine(); // Вывод: The engine of Toyota Camry is started.
      car.move(50); // Вывод: Toyota Camry moved 50 meters.
    
  
TypeScript
    
      abstract class Vehicle {
        make: string;
        model: string;

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

        abstract startEngine(): void; // Абстрактный метод

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

      class Car extends Vehicle {
        constructor(make: string, model: string) {
          super(make, model);
        }

        startEngine(): void {
          console.log(`The engine of ${this.make} ${this.model} is started.`);
        }
      }

      let car = new Car('Toyota', 'Camry');
      car.startEngine(); // Вывод: The engine of Toyota Camry is started.
      car.move(50); // Вывод: Toyota Camry moved 50 meters.
    
  

Здесь абстрактный класс Vehicle содержит абстрактный метод startEngine и метод move. Производный класс Car реализует метод startEngine.

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

JavaScript
    
      "use strict";
      class Employee {
          constructor(name, position) {
              this.name = name;
              this.position = position;
          }
          displayDetails() {
              console.log(`Name: ${this.name}, Position: ${this.position}, Salary: ${this.calculateSalary()}`);
          }
      }
      class FullTimeEmployee extends Employee {
          constructor(name, position, annualSalary) {
              super(name, position);
              this.annualSalary = annualSalary;
          }
          calculateSalary() {
              return this.annualSalary;
          }
      }
      class PartTimeEmployee extends Employee {
          constructor(name, position, hourlyRate, hoursWorked) {
              super(name, position);
              this.hourlyRate = hourlyRate;
              this.hoursWorked = hoursWorked;
          }
          calculateSalary() {
              return this.hourlyRate * this.hoursWorked;
          }
      }
      let fullTimeEmployee = new FullTimeEmployee('Alice', 'Manager', 80000);
      fullTimeEmployee.displayDetails(); // Вывод: Name: Alice, Position: Manager, Salary: 80000
      let partTimeEmployee = new PartTimeEmployee('Bob', 'Consultant', 50, 120);
      partTimeEmployee.displayDetails(); // Вывод: Name: Bob, Position: Consultant, Salary: 6000
    
  
TypeScript
    
      abstract class Employee {
        name: string;
        position: string;

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

        abstract calculateSalary(): number; // Абстрактный метод

        displayDetails(): void {
          console.log(`Name: ${this.name}, Position: ${this.position}, Salary: ${this.calculateSalary()}`);
        }
      }

      class FullTimeEmployee extends Employee {
        annualSalary: number;

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

        calculateSalary(): number {
          return this.annualSalary;
        }
      }

      class PartTimeEmployee extends Employee {
        hourlyRate: number;
        hoursWorked: number;

        constructor(name: string, position: string, hourlyRate: number, hoursWorked: number) {
          super(name, position);
          this.hourlyRate = hourlyRate;
          this.hoursWorked = hoursWorked;
        }

        calculateSalary(): number {
          return this.hourlyRate * this.hoursWorked;
        }
      }

      let fullTimeEmployee = new FullTimeEmployee('Alice', 'Manager', 80000);
      fullTimeEmployee.displayDetails(); // Вывод: Name: Alice, Position: Manager, Salary: 80000

      let partTimeEmployee = new PartTimeEmployee('Bob', 'Consultant', 50, 120);
      partTimeEmployee.displayDetails(); // Вывод: Name: Bob, Position: Consultant, Salary: 6000
    
  

Здесь абстрактный класс Employee содержит абстрактный метод calculateSalary, который реализуется в производных классах FullTimeEmployee и PartTimeEmployee.

Преимущества использования абстрактных классов и методов

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