> For the complete documentation index, see [llms.txt](https://koziuk-s.gitbook.io/angular-starter/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://koziuk-s.gitbook.io/angular-starter/base-typescript/klasi.md).

# Classes

В TypeScript ми можемо використовувати класи, які є аналогічними тим, які ми використовуємо в JavaScript починаючи від стандарту ECMAScript 2015, також відомого як ES6.

Давайте розглянемо простий приклад на основі класу.

{% code title="main.ts" overflow="wrap" lineNumbers="true" %}

```typescript
class User {
  id: number;
  name: string;

  constructor(userId: number, userName: string) {
    this.id = userId;
    this.name = userName;
  }

  getInfo(): string {
    return `id: ${this.id} name: ${this.name}`;
  }
}

let bob = new User(1, 'Bob');

console.log(bob.getInfo()); // id: 1 name: Bob
bob.id = 4;
console.log(bob.getInfo()); // id: 4 name: Bob
```

{% endcode %}

### Модифікатори доступу: public, private і protected.

**Public** - модифікатор, що дозволяє доступ до властивостей і методів класів ззовні.

Якщо до властивостей і методів класів не застосовується ніякий модифікатор, то вони є публічними - public.

{% code title="main.ts" lineNumbers="true" %}

```typescript
class TestUser {
  name: string;
  year: number;
}

// Еквівалентно
class TestUser {
  public name: string;
  public year: number;
}
```

{% endcode %}

**Private** - якщо до властивостей і методів застосовується модифікатор private, то до них не можна буде звернутися ззовні при створенні об'єкта даного класу.

{% code title="main.ts" overflow="wrap" lineNumbers="true" %}

```typescript
class PrivateUser {
  private name: string;
  private year: number;

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

  displayYear(): void {
    console.log('year: ' + this.year);
  }

  displayName(): void {
    console.log('name: ' + this.name);
  }

  private setYear(age: number): number {
    return new Date().getFullYear() - age;
  }
}

let joy = new PrivateUser('Joy', 24);

joy.displayName();
joy.displayYear();

console.log(joy.name); // ERROR: Property 'name' is private and only accessible within class 'PrivateUser'.

joy.setYear(45); // ERROR: Property 'setYear' is private and only accessible within class 'PrivateUser'
```

{% endcode %}

**Protected** — багато в чому аналогічний private, до властивостей і методів не можна буде звернутися ззовні, але до них можна звернутися з класів — спадкоємців, тобто класів які наслідуються від даного класу.

{% code title="main.ts" overflow="wrap" lineNumbers="true" %}

```typescript
class Admin {
  private name: string;
  protected age: number;

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

  displayInfo(): void {
    console.log('name: ' + this.name + ', age: ' + this.age);
  }
}

class Employee extends Admin {
  private company: string;

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

  public showData(): void {
    console.log('Age: ' + this.age);
    console.log('Name: ' + this.name); // ERROR: Property 'name' is private
  }
}
```

{% endcode %}

#### **Readonly**

Також властивості класів можу визначатися як - тільки для читання, значення яких не можна змінювати.

{% code title="main.ts" overflow="wrap" lineNumbers="true" %}

```typescript
class DefaultPoints {
  readonly x = 1;
  readonly y = 1;
}

let defaultPoints = new DefaultPoints();

defaultPoints.x = 0; // ERROR: Cannot assign to 'x' because it is a constant or a read-only property
```

{% endcode %}

Модифікатори можна комбінувати.

{% code title="main.ts" overflow="wrap" lineNumbers="true" %}

```typescript
class DefaultPoints {
  private x = 1;
  private readonly y = 1;
}
```

{% endcode %}

### Абстрастні класи

У TypeScript абстрактний клас - це клас, який не можна створити безпосередньо. Натомість він може слугувати базовим класом, від якого наслідуються інші класи. Абстрактні класи корисні для визначення загального набору властивостей і методів, які повинні мати підкласи.

Як правило, абстрактні класи описують сутності, які в реальності не мають конкретного втілення. Наприклад, геометрична фігура, може представляти коло, квадрат, трикутник, але як такої геометричної фігури самої по собі не існує. Є конкретні фігури, з якими ми й працюємо. Однак всі фігури можуть мати якийсь загальний функціонал. У цьому випадку, ми можемо визначити абстрактний клас фігури, помістити в нього загальний функціонал, і від нього успадкувати класи конкретних геометричних фігур.

Щоб створити абстрактний клас у TypeScript, використовується ключове слово **abstract** перед словом **class**.

{% code title="main.ts" overflow="wrap" lineNumbers="true" %}

```typescript
abstract class SomeFigure {}

let someFigure = new SomeFigure();
// ERROR: Cannot create an instance of an abstract class
```

{% endcode %}

Розглянемо приклад створення абстрактного класу **Figure** який містить абстрактний метод **getArea**.

{% code title="main.ts" overflow="wrap" lineNumbers="true" %}

```typescript
abstract class Figure {
  abstract getArea(): void;
}
```

{% endcode %}

Абстрактний метод не визначає ніякої реалізації. Якщо клас містить абстрактні методи, то такий клас повинен бути абстрактним.

Створимо клас **Rectangle** який розширюється класом **Figure**.

{% code title="main.ts" lineNumbers="true" %}

```typescript
class Rectangle extends Figure {
  constructor(
    public width: number,
    public height: number
  ) {
    super();
  }

  getArea(): void {
    let square = this.width * this.height;

    console.log("area =", square);
  }
}

let rectangle: Figure = new Rectangle(20, 30);
rectangle.getArea();
```

{% endcode %}

Зверніть увагу, що при спадкуванні, похідні класи зобов'язані реалізувати всі абстрактні методи.

Також на відміну від інтерфейсів, абстрактний клас може надавати деталі реалізації та містити деякі властивості, тоді як інтерфейс визначає лише форму об'єкта і не містить жодних деталей реалізації.
