Знакомство с классами в TypeScript

4-11-2019

В TypeScript реализован ООП подход на основе классов. Одним из основных шаблонов объектно-ориентированного программирования является наследование классов. С помощью него можно создавать новые классы на основе существующих.

Немного определений:

Ключевое слово extends используется для создания подкласса на основе другого класса, который еще называют базовым.

Статичные свойства — это свойства, значения которых одинаковы для всех экземпляров класса. Определяются такие свойства с помощью ключевого слова static. Доступ к таким свойствам осуществляется по шаблону <ClassName>.<PropertyName>.

Абстрактный класс — это базовый класс, на основе которого могут быть созданы другие классы при помощи наследования. В отличие от обычных классов, экземпляр абстрактного создать нельзя. Для объявления абстрактного класса используется ключевое слово abstract. Тоже самое применимо и для методов и свойств. Абстрактные методы не должны быть реализованы и должны быть переопределены в производном классе. Они похожи по синтаксису на определение методов в интерфейсе. И интерфейс, и абстрактный класс определяют сигнатуру метода без реализации, но абстрактные методы должны быть определены с помощью ключевого слова abstract и могут иметь модификаторы доступа. Поскольку класс представляет собой тип данных с определенной структурой, можно использовать его так, как будто это интерфейс.

Простой пример класса

Пример работы с классами:

// Общее использование
class  Vehicle  {
	drive():  void  {console.log ('Кручу, кручу, педали кручу!')}
	beep():  void  {console.log('Дзынь!')}
}


// пример наследования
class  Car  extends  Vehicle{
}

// пример наследования с переопределением методов базового класса
class  Moto  extends  Vehicle  {
	drive():  void  {console.log ('Дрын, дрын, дрын ...')}
}

class  Train  extends  Vehicle  {
	drive():  void  {console.log('Чух, чух, чух ...')}
	beep():  void  {console.log('Ту-у, ту-у!')}
}


const  v  =  new Vehicle();
v.drive();
v.beep();

const  c  =  new Car();
c.drive();
c.beep();

const  m  =  new Moto();
m.drive();
m.beep();

const  t  =  new Train();
t.drive();
t.beep();

Запустив указанный пример, мы получим следующий результат:

$ ts-node classes.ts
Кручу, кручу, педали кручу!
Дзынь!

Кручу, кручу, педали кручу!
Дзынь!

Дрын, дрын, дрын ...
Дзынь!

Чух, чух, чух ...
Ту-у, ту-у!

Модификаторы доступа

Примеры:

// пример с модификаторами доступа

//public - этот метод может быть вызван везде (в классе, в его наследниках, в его экземплярах) в любое время.
// По умолачанию все методы являются таковыми.

//private - этот метод может быть вызван только через другие методы ЭТОГО (this) класса

//protected - этот метод может быть вызван другими методами ЭТОГО (this) класса, 
//или другими методами дочерних классов

class  Vehicle  {
name:  string  =  'Велосипед';
public  owner:  string  =  'Вася'  // видимость такая же как у свойства name
private  need_repairing:  boolean  =  false;  // видна только для методов класса Vehicle
protected  repaired:  boolean  =  true;  // видна только для методов класса Vehicle, а также его наследников

	drive():  void  {  // можно запустить в этом классе, в его наследниках и экземплярах класса Vehicle
	console.log ('Кручу, кручу, кручу педали кручу!')
	}

	public  beep():  void  {  // можно запустить в этом классе, в его наследниках и экземплярах класса Vehicle
	//(видимость такая же как у метода drive)
	console.log('Дзынь!')
	}

	private  sell():  void  {  // можно запустить ТОЛЬКО через методы этого класса см. v.sell();
	console.log(`Продаю ${this.name} - этот метод имеет модификатор Private в Базовом классе Vehicle`)
	}

    protected  repair():  void  {// можно запустить ТОЛЬКО через методы этого класса см. v.repair(); 
                                //и в методах наследников
	console.log('Метод ремонта - Protected')
	}

	repairing():void  {
	if (this.repaired) {
	console.log('------Вызов метода repairing() --------')
	this.need_repairing  =  false
	this.drive()
	this.sell()
	console.log('-------------------')
	}  else  {  console.log('------нужно чинить! --------')}
	}
}

  

const  v  =  new Vehicle();
v.drive();
v.beep();
v.name =  'Самолёт'
v.owner  =  'Чкалов'
console.log(v.name);
console.log(v.owner);
v.repairing();
// при запуске v.sell(); будет ошибка: Property 'sell' is private and only accessible within class 'Vehicle'.

// при запуске v.repair(); будет ошибка: Property 'repair' is protected and only accessible within class 'Vehicle' 
//and its subclasses.

// при запуске v.need_repairing будет ошибка: Property 'need_repairing' is private and only accessible 
//within class 'Vehicle'.

// при запуске v.repaired будет ошибка: Property 'repaired' is protected and only accessible within class 'Vehicle' 
//and its subclasses.

  
// пример c наследованием
class  Car  extends  Vehicle{
name:  string  =  'Автомобиль';
	beep()  {
	console.log('Бибип!')
	}

	drive()  {
	console.log('Р-р-р-рр-р ...')
    this.repaired  =  false  //свойство repaired может быть использовано в наследниках класса Vehicle,
                           // но не в наследниках
	console.log(this.repaired)
	this.repair() //метод repair может быть запущен в наследниках класса Vehicle, а не в экземплярах,
	              //ибо он имеет модификатор доступа Protected в родительском классе Vehicle
	}
}

  
const  c  =  new Car();
c.drive();
c.beep();
console.log(c.name);
console.log(c.owner);
c.repairing();
// при запуске c.sell(); будет ошибка: Property 'sell' is private and only accessible within class 'Vehicle'.

// при запуске c.repair(); будет ошибка: Property 'repair' is protected and only accessible within class 'Vehicle' 
//and its subclasses.

// при запуске c.need_repairing будет ошибка: Property 'need_repairing' is private and only accessible 
//within class 'Vehicle'.

// при запуске c.repaired будет ошибка: Property 'repaired' is protected and only accessible within 
//class 'Vehicle' and its subclasses.

Результат запуска:

$ ts-node classes.ts

Кручу, кручу, кручу педали кручу!
Дзынь!
Самолёт
Чкалов
------Вызов метода repairing() --------
Кручу, кручу, кручу педали кручу!
Продаю Самолёт - этот метод имеет модификатор Private в Базовом классе Vehicle
-------------------

Р-р-р-рр-р ...
false
Метод ремонта - Protected
Бибип!
Автомобиль
Вася
------нужно чинить! --------