Об'єктно-орієнтоване програмування (OOP) — це парадигма програмування, що використовується для організації та моделювання програмного забезпечення. Вона акцентує увагу на використанні об'єктів, які поєднують дані та методи, що оперують цими даними.
Основні концепції OOP:
- Клас: Шаблон для створення об'єктів з властивостями та методами.
- Об'єкт: Екземпляр класу.
- Наслідування: Можливість класу успадковувати властивості та методи від іншого класу.
- Поліморфізм: Можливість перевизначати методи у похідних класах.
- Інкапсуляція: Приховування внутрішніх станів об'єкта і відкриття лише необхідних частин.
- Абстракція: Приховування складних деталей реалізації та показ лише суттєвих характеристик.
- Модифікатори доступу: Контролюють видимість членів класу.
1. Клас і Об'єкт
Клас визначає структуру об'єкта, включаючи його властивості та методи.
// Оголошення класу
class Animal {
constructor(public name: string, public species: string, public sound: string) {}
makeSound() {
console.log(`Тварина ${this.species} на ім'я ${this.name} каже ${this.sound}`);
}
}
// Створення об'єктів (екземплярів)
const dog = new Animal("Німецька вівчарка", "собака", "гхев гхев гхев");
const cat = new Animal("Кішка", "кіт", "мяу мяу");
dog.makeSound();
cat.makeSound();
2. Наслідування
Наслідування дозволяє класу успадковувати методи та властивості від іншого класу.
class Person {
constructor(public name: string, public age: number, public address: string) {}
sleep(numOfHours: number) {
console.log(`${this.name} спить ${numOfHours} годин.`);
}
}
class Teacher extends Person {
constructor(name: string, age: number, address: string, public designation: string) {
super(name, age, address);
}
teach(numOfClasses: number) {
console.log(`${this.name} проведе ${numOfClasses} уроків(ів).`);
}
}
const teacher = new Teacher("Містер Ариф", 54, "Кумархалі", "Асистент вчителя");
teacher.sleep(7);
teacher.teach(3);
3. Захист типів
Захист типів допомагає визначити тип змінної в певному блоці коду.
type AlphaNumeric = string | number;
const add = (param1: AlphaNumeric, param2: AlphaNumeric): AlphaNumeric => {
if (typeof param1 === "number" && typeof param2 === "number") {
return param1 + param2;
} else {
return param1.toString() + param2.toString();
}
};
console.log(add("213", "56")); // Виводить: "21356"
Використання оператора in
:
type NormalUser = { name: string };
type AdminUser = { name: string; role: "admin" };const getUser = (user: NormalUser | AdminUser) => {
if ('role' in user) {
console.log(`Я адміністратор. Моє ім'я ${user.name}, а роль — ${user.role}`);
} else {
console.log(`Я звичайний користувач. Моє ім'я ${user.name}`);
}
};const adminUser: AdminUser = { name: "Адміністратор Єва", role: "admin" };
getUser(adminUser); // Виводить: "Я адміністратор. Моє ім'я Адміністратор Єва, а роль — admin"
4. Захист типів за допомогою instanceof
Використання instanceof
для відрізнення між різними класами.
class Animal {
constructor(public name: string, public species: string) {}makeSound() {
console.log("Я видаю звук!");
}
}class Dog extends Animal {
makeBark() {
console.log("Я гавкаю!");
}
}class Cat extends Animal {
makeMew() {
console.log("Мяу мяу!");
}
}const isDog = (animal: Animal): boolean => animal instanceof Dog;
const isCat = (animal: Animal): boolean => animal instanceof Cat;const getAnimal = (animal: Animal) => {
if (animal instanceof Dog) {
animal.makeBark();
} else if (animal instanceof Cat) {
animal.makeMew();
}
};const dog = new Dog("Німецька вівчарка", "собака");
const cat = new Cat("Кішка", "кіт");getAnimal(dog); // Виводить: "Я гавкаю!"
getAnimal(cat); // Виводить: "Мяу мяу!"
Модифікатори доступу
Модифікатори доступу контролюють видимість членів класу.
- `public`: За замовчуванням доступний всюди.
- `private`: Доступний лише всередині класу.
- `protected`: Доступний у класі та його підкласах.
class BankAccount {
readonly id: number; // Readonly
private balance: number; // Private, cannot be accessed directlyconstructor(id: number, name: string, balance: number) {
this.id = id;
this.balance = balance;
}deposit(amount: number) {
this.balance += amount;
}getBalance() {
console.log(`Баланс: ${this.balance});
``
}
}const account = new BankAccount(123, "Asif", 1000);
account.deposit(500);
account.getBalance(); // Виводить: "Баланс: 1500"
6. Геттери та Сеттери
Геттери та сеттери дозволяють керувати доступом до властивостей.
class BankAccount {
private _balance: number;constructor(private id: number, private name: string, balance: number) {
this._balance = balance;
}// Геттер для балансу
get balance(): number {
return this._balance;
}// Сеттер для депозиту
set deposit(amount: number) {
this._balance += amount;
}
}const account = new BankAccount(123, "Asif", 1000);
account.deposit = 500;
console.log(account.balance); // Виводить: 1500
7. Статичні члени
Статичні члени належать самому класу, а не його екземплярам.
class Counter {
static count: number = 0;
static increase() {
Counter.count += 1;
}
static decrease() {
Counter.count -= 1;
}
}
Counter.increase();
Counter.increase();
Counter.decrease();
console.log(Counter.count); // Виводить: 1
8. Поліморфізм
Поліморфізм дозволяє різним класам надавати власну реалізацію методу, визначеного в батьківському класі.
class Person {
getSleep() {
console.log("Я сплю 8 годин на день.");
}
}class Student extends Person {
getSleep() {
console.log("Я сплю 7 годин на день.");
}
}class Developer extends Person {
getSleep() {
console.log("Я сплю 6 годин на день.");
}
}const getSleepingHours = (person: Person) => person.getSleep();const student = new Student();
const developer = new Developer();getSleepingHours(student); // Виводить: "Я сплю 7 годин на день."
getSleepingHours(developer); // Виводить: "Я сплю 6 годин на день."
9. Абстракція
Абстракція приховує деталі реалізації та показує лише суттєві характеристики.
Використання інтерфейсу:
interface Vehicle {
startEngine(): void;
stopEngine(): void;
move(): void;
}
class Car implements Vehicle {
startEngine() {
console.log("Запуск двигуна автомобіля...");
}
stopEngine() {
console.log("Зупинка двигуна автомобіля...");
}
move() {
console.log("Автомобіль рухається...");
}
}
const car = new Car();
car.startEngine(); // Виводить: "Запуск двигуна автомобіля..."
Використання абстрактного класу:
abstract class Vehicle {
abstract startEngine(): void;
abstract stopEngine(): void;
abstract move(): void;
}
class Car extends Vehicle {
startEngine() {
console.log("Запуск двигуна автомобіля...");
}
stopEngine() {
console.log("Зупинка двигуна автомобіля...");
}
move() {
console.log("Автомобіль рухається...");
}
}
const car = new Car();
car.startEngine(); // Виводить: "Запуск двигуна автомобіля..."
class Car extends Vehicle {
startEngine() {
console.log("Запуск двигуна автомобіля...");
} stopEngine() {
console.log("Зупинка двигуна автомобіля...");
} move() {
console.log("Автомобіль рухається...");
}
}const car = new Car();
car.startEngine(); // Виводить: "Запуск двигуна автомобіля..."
Інкапсуляція
Інкапсуляція — це концепція об'єднання даних і методів, що оперують цими даними, в єдину одиницю, з обмеженням доступу до деяких компонентів об'єкта.
class BankAccount {
private _balance: number;
constructor(private id: number, private name: string, balance: number) {
this._balance = balance;
}
deposit(amount: number) {
this._balance += amount;
}
getBalance() {
console.log(Баланс: ${this._balance}
);
}
}
const account = new BankAccount(123, "Asif", 1000);
account.deposit(500);
account.getBalance(); // Виводить: "Баланс: 1500"
Перекладено з: Object-Oriented Programming (OOP) in TypeScript