JavaRush /Курсы /Модуль 2: Fullstack /Интерфейсы и классы

Интерфейсы и классы

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

9.1 Совместная работа интерфейсов и классов

Интерфейсы позволяют описывать контракты, которым должны соответствовать объекты, а классы обеспечивают реализацию этих контрактов. Совместное использование интерфейсов и классов позволяет создать гибкий и поддерживаемый код, который легко расширять и модифицировать.

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

Интерфейсы

Интерфейсы в TypeScript используются для определения контрактов, которые должны соблюдать объекты. Они описывают структуру объектов, определяя набор свойств и методов, которые должны быть у объекта.

Пример:

JavaScript
    
      "use strict";
      let person = {
          name: 'Alice',
          age: 30,
          greet() {
              console.log(`Hello, my name is ${this.name}.`);
          }
      };
      person.greet(); // Вывод: Hello, my name is Alice.
    
  
TypeScript
    
      interface Person {
        name: string;
        age: number;
        greet(): void;
      }

      let person: Person = {
        name: 'Alice',
        age: 30,
        greet() {
          console.log(`Hello, my name is ${this.name}.`);
        }
      };

      person.greet(); // Вывод: Hello, my name is Alice.
    
  

Классы

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

Пример:

JavaScript
    
      "use strict";
      class Employee {
          constructor(name, age, position) {
              this.name = name;
              this.age = age;
              this.position = position;
          }
          greet() {
              console.log(`Hello, my name is ${this.name} and I am a ${this.position}.`);
          }
      }
      let employee = new Employee('Bob', 40, 'Manager');
      employee.greet(); // Вывод: Hello, my name is Bob and I am a Manager.
    
  
TypeScript
    
      interface Person {
        name: string;
        age: number;
        greet(): void;
      }

      class Employee implements Person {
        name: string;
        age: number;
        position: string;

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

        greet(): void {
          console.log(`Hello, my name is ${this.name} and I am a ${this.position}.`);
        }
      }

      let employee = new Employee('Bob', 40, 'Manager');
      employee.greet(); // Вывод: Hello, my name is Bob and I am a Manager.
    
  

В этом примере класс Employee реализует интерфейс Person, гарантируя, что все свойства и методы интерфейса будут определены в классе.

9.2 Реализация интерфейсов в классах

Когда класс реализует интерфейс, он должен предоставить реализацию всех свойств и методов, определенных в интерфейсе. Это помогает гарантировать, что класс соответствует определенному контракту.

Пример реализации интерфейсов:

JavaScript
    
      "use strict";
      class Dog {
          constructor(name) {
              this.name = name;
          }
          makeSound() {
              console.log('Woof! Woof!');
          }
      }
      class Cat {
          constructor(name) {
              this.name = name;
          }
          makeSound() {
              console.log('Meow! Meow!');
          }
      }
      let dog = new Dog('Rex');
      dog.makeSound(); // Вывод: Woof! Woof!
      let cat = new Cat('Whiskers');
      cat.makeSound(); // Вывод: Meow! Meow!
    
  
TypeScript
    
      interface Animal {
        name: string;
        makeSound(): void;
      }

      class Dog implements Animal {
        name: string;

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

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

      class Cat implements Animal {
        name: string;

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

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

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

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

Здесь классы Dog и Cat реализуют интерфейс Animal, что гарантирует наличие свойства name и метода makeSound в обоих классах.

Наследование интерфейсов

Интерфейсы в TypeScript могут наследовать другие интерфейсы, что позволяет создавать сложные типы на основе более простых.

Пример синтаксиса наследования интерфейсов:

JavaScript
    
      "use strict";
      let employee = {
          name: 'Alice',
          age: 30,
          position: 'Developer',
          salary: 80000
      };
      console.log(employee);
    
  
TypeScript
    
      interface Person {
        name: string;
        age: number;
      }

      interface Employee extends Person {
        position: string;
        salary: number;
      }

      let employee: Employee = {
        name: 'Alice',
        age: 30,
        position: 'Developer',
        salary: 80000
      };

      console.log(employee);
    
  

Здесь интерфейс Employee наследует интерфейс Person, добавляя свойства position и salary.

9.3 Реализация нескольких интерфейсов

Класс в TypeScript может реализовывать несколько интерфейсов, что позволяет комбинировать различные контракты.

Синтаксис реализации нескольких интерфейсов:

JavaScript
    
      "use strict";
      class FlyingCar {
          drive() {
              console.log('Driving on the road...');
          }
          fly() {
              console.log('Flying in the sky...');
          }
      }
      let myFlyingCar = new FlyingCar();
      myFlyingCar.drive(); // Вывод: Driving on the road...
      myFlyingCar.fly(); // Вывод: Flying in the sky...
    
  
TypeScript
    
      interface Drivable {
        drive(): void;
      }

      interface Flyable {
        fly(): void;
      }

      class FlyingCar implements Drivable, Flyable {
        drive(): void {
          console.log('Driving on the road...');
        }

        fly(): void {
          console.log('Flying in the sky...');
        }
      }

      let myFlyingCar = new FlyingCar();
      myFlyingCar.drive(); // Вывод: Driving on the road...
      myFlyingCar.fly(); // Вывод: Flying in the sky...
    
  

В этом примере класс FlyingCar реализует интерфейсы Drivable и Flyable, что позволяет объекту myFlyingCar ездить и летать.

9.4 Интерфейсы и классы в реальных проектах

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

Пример 1: Управление пользователями

JavaScript
    
      "use strict";
      class Admin {
          constructor(id, name, email, adminLevel) {
              this.id = id;
              this.name = name;
              this.email = email;
              this.adminLevel = adminLevel;
          }
          getDetails() {
              return `Admin: ${this.name} (Level ${this.adminLevel})`;
          }
      }
      class Member {
          constructor(id, name, email, membershipType) {
              this.id = id;
              this.name = name;
              this.email = email;
              this.membershipType = membershipType;
          }
          getDetails() {
              return `Member: ${this.name} (${this.membershipType} Membership)`;
          }
      }
      let admin = new Admin(1, 'Alice', 'alice@example.com', 5);
      console.log(admin.getDetails()); // Вывод: Admin: Alice (Level 5)
      let member = new Member(2, 'Bob', 'bob@example.com', 'Gold');
      console.log(member.getDetails()); // Вывод: Member: Bob (Gold Membership)
    
  
TypeScript
    
      interface User {
        id: number;
        name: string;
        email: string;
        getDetails(): string;
      }

      class Admin implements User {
        id: number;
        name: string;
        email: string;
        adminLevel: number;

        constructor(id: number, name: string, email: string, adminLevel: number) {
          this.id = id;
          this.name = name;
          this.email = email;
          this.adminLevel = adminLevel;
        }

        getDetails(): string {
          return `Admin: ${this.name} (Level ${this.adminLevel})`;
        }
      }

      class Member implements User {
        id: number;
        name: string;
        email: string;
        membershipType: string;

        constructor(id: number, name: string, email: string, membershipType: string) {
          this.id = id;
          this.name = name;
          this.email = email;
          this.membershipType = membershipType;
        }

        getDetails(): string {
          return `Member: ${this.name} (${this.membershipType} Membership)`;
        }
      }

      let admin = new Admin(1, 'Alice', 'alice@example.com', 5);
      console.log(admin.getDetails()); // Вывод: Admin: Alice (Level 5)

      let member = new Member(2, 'Bob', 'bob@example.com', 'Gold');
      console.log(member.getDetails()); // Вывод: Member: Bob (Gold Membership)
    
  

Здесь классы Admin и Member реализуют интерфейс User, добавляя специфичные для них свойства и методы.

Пример 2: Оплата заказов

JavaScript
    
      "use strict";
      class CreditCard {
          constructor(cardNumber) {
              this.cardNumber = cardNumber;
          }
          processPayment(amount) {
              console.log(`Processing credit card payment of $${amount} using card ${this.cardNumber}.`);
          }
      }
      class PayPal {
          constructor(email) {
              this.email = email;
          }
          processPayment(amount) {
              console.log(`Processing PayPal payment of $${amount} using email ${this.email}.`);
          }
      }
      let paymentMethod;
      paymentMethod = new CreditCard('1234-5678-8765-4321');
      paymentMethod.processPayment(100); // Вывод: Processing credit card payment of $100 using card 1234-5678-8765-4321.
      paymentMethod = new PayPal('user@example.com');
      paymentMethod.processPayment(200); // Вывод: Processing PayPal payment of $200 using email user@example.com.
    
  
TypeScript
    
      interface PaymentMethod {
        processPayment(amount: number): void;
      }

      class CreditCard implements PaymentMethod {
        cardNumber: string;

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

        processPayment(amount: number): void {
          console.log(`Processing credit card payment of $${amount} using card ${this.cardNumber}.`);
        }
      }

      class PayPal implements PaymentMethod {
        email: string;

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

        processPayment(amount: number): void {
          console.log(`Processing PayPal payment of $${amount} using email ${this.email}.`);
        }
      }

      let paymentMethod: PaymentMethod;

      paymentMethod = new CreditCard('1234-5678-8765-4321');
      paymentMethod.processPayment(100); // Вывод: Processing credit card payment of $100 using card 1234-5678-8765-4321.

      paymentMethod = new PayPal('user@example.com');
      paymentMethod.processPayment(200); // Вывод: Processing PayPal payment of $200 using email user@example.com.
    
  

В этом примере интерфейс PaymentMethod используется для определения контракта, который должны реализовывать различные способы оплаты, такие как CreditCard и PayPal.

Преимущества совместного использования интерфейсов и классов

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