Класс — это образец создания объектов. Он определяет свойства и методы, которыми будут обладать объекты, созданные этим классом. Введение классов в ECMAScript (ES6) было направлено на обеспечение более структурированного и объектно-ориентированного способа создания объектов и управления ими.
В этой статье мы рассмотрим следующие темы:
- Как создать класс.
- Использование конструкторов в классах.
- Статические методы и свойства
- Геттеры и сеттеры
- Наследование
- Как использовать TypeScript для улучшения классов
Синтаксический сахар
Раньше мы могли создавать объекты с прототипами, но синтаксис был слишком многословным. В результате были введены классы, и новый класс просто наследует, что такое прототипы и их методы.
До ES6:
function Book(title, author, releaseYear){ this.title = title; this.author = author; this.releaseYear = releaseYear; } Book.prototype.getOverview = function(){ return `The book ${this.title} written by ${this.author} was released in ${this.releaseYear}.`; } const book = new Book("Atomic Habits", "James Clear", 2018); console.log(book.getOverview());
После ES6:
class Book { constructor(title, author, releaseYear){ this.title = title; this.author = author; this.releaseYear = releaseYear; } getOverview(){ return `The book ${this.title} written by ${this.author} was released in ${this.releaseYear}.`; } } const book = new Book("Atomic Habits", "James Clear", 2018); console.log(book.getOverview());
Определение класса
Чтобы определить класс, нам нужно использовать ключевое слово class
, за которым следует его имя и фигурные скобки.
class Book {}
Класс может иметь constructor
— специальный метод внутри класса, который автоматически вызывается при создании экземпляра класса или объекта. Целью constructor
является инициализация состояния объекта или выполнение любых операций настройки, необходимых для правильной работы объекта. В нашем примере мы присваиваем нашему классу свойства, к которым мы сможем получить доступ позже.
class Book { constructor(title, author, releaseYear){ this.title = title; this.author = author; this.releaseYear = releaseYear; } }
Примечание. Классы могут иметь только один constructor
. JavaScript не поддерживает перегрузку конструкторов или методов.
Классы могут содержать свойства, примитивные или непримитивные типы и методы (функции). Хотя можно явно добавлять свойства к классу за пределами constructor
, рекомендуемый подход — присваивать их непосредственно внутри constructor
.
class Book { // This is possible, but redundant in this scenario since we've already defined these properties within the constructor. title; author; releaseYear; constructor(title, author, releaseYear){ this.title = title; this.author = author; this.releaseYear = releaseYear; } }
Для определения методов в классах мы используем синтаксис, аналогичный функциям, но без необходимости использования ключевого слова function
.
class Book { constructor(title, author, releaseYear){ this.title = title; this.author = author; this.releaseYear = releaseYear; } // We omit the function keyword getOverview(){ return `The book ${this.title} written by ${this.author} was released in ${this.releaseYear}.`; } }
Чтобы сделать класс полезным, нам нужно создать экземпляр объекта этого класса, используя ключевое слово new
, за которым следует вызов constructor
с правильными аргументами:
const book = new Book("Atomic Habits", "James Clear", 2018);
Если мы не предоставим constructor
, внутри будет установлено значение по умолчанию:
constructor(){}
Примечание. Класс не поднимается наверх, в отличие от функций. Чтобы избежать ошибок, объявляйте их перед созданием объектов этого типа.
Статическое ключевое слово
Доступ к методу или свойству static
можно получить непосредственно из самого класса, без необходимости создания экземпляра класса. Эта функция особенно ценна для служебных функций или постоянных переменных.
class Utilities { static PI = 3.14; static max(a, b){ return a > b ? a : b; } } console.log(Utilities.PI); // Output: 3.14 console.log(Utilities.max(1,2)); // Output: 2
Если вы знакомы с классом JavaScript Math
, понимание этой концепции станет более простым.
Частная недвижимость
К частному свойству или методу невозможно получить доступ извне класса. Чтобы определить такое свойство или метод, мы используем символ #
.
class Book { #ISBN = 5; constructor(title, author, releaseYear, price){ this.title = title; this.author = author; this.releaseYear = releaseYear; this._price = price; } #getOverview(){ return `The book ${this.title} written by ${this.author} was released in ${this.releaseYear}.`; } } const book = new Book("Atomic Habits", "James Clear", 2018, 120); //This will throw an error: "getOverview is not a function" book.getOverview(); //This will return undefined book.ISBN;
Геттеры и сеттеры
Свойства предлагают гибкий способ получения и установки значений без необходимости прямого доступа к базовым данным. Эта гибкость повышает удобство сопровождения и инкапсуляцию кода.
Мы можем улучшить наш класс Book
, введя частное свойство с именем price
. Чтобы защитить его от недопустимых значений, мы будем использовать метод установки, сохраняя при этом возможность доступа к нему с помощью метода получения.
class Book { constructor(title, author, releaseYear, price){ this.title = title; this.author = author; this.releaseYear = releaseYear; this._price = price; } // Getter get price() { return this._price; } // Setter set price(newPrice){ if(this._price === 0) throw new Error("Price can't be zero"); this._price = newPrice; } } // Usage const book = new Book("Atomic Habits", "James Clear", 2018, 120); console.log(`Price: $${book.price}`); book.price = 10; console.log(`Price: $${book.price}`);
Стоит отметить, что мы не вызывали метод установки явно; вместо этого мы использовали прямое присвоение. То же самое относится и к методу получения. Эта функция предлагает удобный и элегантный подход к работе со свойствами нашего класса.
Наследование
Для начала важно понять фундаментальные концепции суперкласса и производных классов.
Суперкласс, также известный как базовый класс или родительский класс, — это класс, от которого другие классы наследуют свойства и методы.
Производный класс, также известный как подкласс или дочерний класс, — это класс, который наследует атрибуты и методы суперкласса.
Наследование — это фундаментальная концепция объектно-ориентированного программирования, обеспечивающая повторное использование кода, расширяемость и организацию классов в иерархии.
Например, мы хотим создать Technical Book
со свойством издания. Мы знаем, что Technical Book
— это Book
, поэтому мы расширяем класс Book
, чтобы сделать его свойства доступными для нашего нового класса.
class Book { constructor(title, author, releaseYear, price){ this.title = title; this.author = author; this.releaseYear = releaseYear; this._price = price; } } class TechnicalBook extends Book { constructor(title, author, releaseYear, price, edition){ super(title, author, releaseYear, price); this.edition = edition; } } const technicalBook = new TechnicalBook("Atomic Habits", "James Clear", 2018, 120, 1); console.log(`Edition ${technicalBook.edition} of the book ${technicalBook.title}`);
Мы используем ключевое слово super
для вызова конструктора суперкласса Book
из нашего производного класса TechnicalBook
. Это делается для доступа и выполнения поведения, определенного в суперклассе, которое затем можно расширить или настроить в производном классе.
Использование машинописного текста
TypeScript — это статически типизированная расширенная версия JavaScript, которая поддерживает классы для объектно-ориентированного программирования.
Модификаторы доступа
Существует 3 модификатора доступа:
public
— доступ к свойствам и методам возможен вне класса.private
— доступ к свойствам и методам возможен только внутри класса. Производные классы не имеют доступа к этим свойствам или методам.protected
— доступ к свойствам и методам возможен только внутри класса или производных классов.
По умолчанию все методы и свойства являются частными.
class Book implements IBook { public title: string; private author: string; protected releaseYear: number; public constructor(title: string, author: string, releaseYear: number){ this.title = title; this.author = author; this.releaseYear = releaseYear; } public getOverview(){ return `The book ${this.title} written by ${this.author} was released in ${this.releaseYear}.`; } }
Взгляните на этот хитрый метод использования модификаторов доступа для непосредственной инициализации свойств в списке параметров конструктора.
class Book { public constructor(public title: string, private author: string, protected releaseYear: number){} public getOverview(){ return `The book ${this.title} written by ${this.author} was released in ${this.releaseYear}.`; } }
Интерфейсы
Интерфейс служит контрактом, которого должен придерживаться класс. Это обязывает класс реализовать указанные свойства и методы, указанные в интерфейсе. Это обеспечивает соблюдение четкого набора правил и ожиданий относительно того, как должен вести себя класс.
interface IBook { title: string; author: string; releaseYear: number; getOverview: () => string; } class Book implements IBook { public title: string; public author: string; public releaseYear: number; public constructor(title: string, author: string, releaseYear: number){ this.title = title; this.author = author; this.releaseYear = releaseYear; } getOverview(){ return `The book ${this.title} written by ${this.author} was released in ${this.releaseYear}.`; } }
Абстрактный класс
В TypeScript абстрактный класс — это класс, экземпляр которого не может быть создан сам по себе, но служит основой для других классов. Абстрактные классы позволяют определять общие методы и свойства, которые должны быть реализованы производными классами. Чтобы создать абстрактный класс в TypeScript, вы используете ключевое слово abstract
. Вот базовый пример:
abstract class Shape { abstract calculateArea(): number; displayArea() { console.log(`Area: ${this.calculateArea()}`); } } class Circle extends Shape { constructor(private radius: number) { super(); } calculateArea(): number { return Math.PI * Math.pow(this.radius, 2); } } const circle = new Circle(5); circle.displayArea(); // Output: Area: 78.53981633974483
Если эта статья показалась вам интересной, пожалуйста, подумайте о том, чтобы оставить комментарий или оставить отзыв. Ваши отзывы мотивируют меня создавать больше контента. Если у вас есть какие-либо вопросы или конкретные темы, о которых вы хотели бы, чтобы я написал, пожалуйста, оставляйте комментарии со своими предложениями. Я ценю вашу поддержку и вклад!
Стеккадемический
Спасибо, что дочитали до конца. Прежде чем уйти:
- Пожалуйста, рассмотрите возможность аплодировать и следовать автору! 👏
- Подпишитесь на нас в Twitter(X), LinkedIn и YouTube.
- Посетите Stackademic.com, чтобы узнать больше о том, как мы демократизируем бесплатное образование в области программирования во всем мире.