Методы в TypeScript
1. Что это за метод?
В языке программирования TypeScript метод представляет собой блок кода (block of code), определенный внутри класса и выполняемый только при вызове. Методы разделяют большую задачу на мелкие части и выполняют конкретную операцию этой программы. Этот процесс повышает возможность повторного использования кода и расширяет модульный подход программы.
В основном методы делятся на 3 типа:
- Регулярный метод (нестатический и неабстрактный).
- Статический метод (static method).
- Абстрактный метод (abstract method).
2. Регулярный метод
Синтаксис для определения регулярного метода:
[private | protected | public] method_name(arguments) : return_type {
// statement(s)
}
- return_type: Возвращаемый тип данных метода. Используйте ключевое слово void в качестве типа возвращаемого значения, если метод ничего не возвращает.
- method_name:Имя метода. В отличие от других языков, таких как Java, TypeScript не допускает двух методов с одинаковым именем, даже если они имеют разные параметры. Это необходимо для преобразования кода TypeScript в Javascript.
- arguments: Параметры метода.
Например: класс Cat и метод sayHello(..). Чтобы вызвать sayHello(..), необходимо создать объект Cat и вызвать метод, используя точечную нотацию (dot notation).
method_ex1.ts
class Cat {
sayHello(name: string): void {
console.log(`Hello ${name}`);
}
}
function method_ex1_test() {
var tom: Cat = new Cat(); // Create a Cat object.
tom.sayHello("Jerry"); // Call the method through the object.
}
// Call the method:
method_ex1_test();
Output:
Hello Jerry
Метод может содержать 0, 1 или более параметров, разделенных запятыми.
method_ex2.ts
class Rectangle {
width: number;
height: number;
constructor(width: number, height: number) {
this.width = width;
this.height = height;
}
getArea(): number {
return this.width * this.height;
}
changeWidthHeight(newWidth: number, newHeight: number): void {
this.width = newWidth;
this.height = newHeight;
}
showMe(): void {
console.log(`I am a rectangle, width: ${this.width}, height: ${this.height}`);
}
}
function method_ex2_test() {
var rec = new Rectangle(5, 10); // Create an object.
rec.showMe(); // Call the method.
var area = rec.getArea(); // Call the method.
console.log(`Area: ${area}`);
console.log(` --- Change width and height --- `);
rec.changeWidthHeight(25, 15); // Set newWidth, newHeight
rec.showMe(); // Call the method.
area = rec.getArea(); // Call the method.
console.log(`Area: ${area}`);
}
method_ex2_test(); // Call the function.
Output:
I am a rectangle, width: 5, height: 10
Area: 50
--- Change width and height ---
I am a rectangle, width: 25, height: 15
Area: 375
3. Статический метод
TypeScript использует ключевое слово static в сочетании с синтаксисом определения обычного метода для определения статического метода.
Синтаксис:
[private | protected | public] static method_name(arguments) : return_type {
// statement(s)
}
Характеристики статических методов:
- Статический метод вызывается с помощью имени класса и точечной нотации. Например, MyUtility.sum(100, 50).
- Нестатические члены класса не могут отображаться в статическом методе, если к ним не осуществляется доступ через объект (см. Пример ниже).
method_static_ex1.ts
class MyUtility {
static sum(a: number, b: number): number { // same as 'public'
return a + b;
}
public static minus(a: number, b: number): number {
return a - b;
}
}
function method_static_ex1_test() {
var result = MyUtility.sum(100, 50);
console.log(`Sum Result: ${result}`);
result = MyUtility.minus(100, 50);
console.log(`Minus Result: ${result}`);
}
method_static_ex1_test(); // Call the method
Output:
Sum Result: 150
Minus Result: 50
Затем посмотрите на приведенный ниже пример:
- side1, side2 и side3 являются нестатическими полями класса Triangle, они не могут отображаться в статическом методе.
method_static_ex2.ts
class Triangle {
side1: number; side2: number; side3: number;// Non-static fields (Cann't use in static method)
static DEFAULT_COLOR:string = 'blue'; // Static field (Can use in static method)
constructor(s1: number, s2: number, s3: number) {
var valid = Triangle.isValidSides(s1, s2, s3); // Check if all sides are valid.
if (!valid) {
throw new Error('Invalid Sides!'); // Throw an Error.
}
this.side1 = s1;
this.side2 = s2;
this.side3 = s3;
}
static isValidSides(s1: number, s2: number, s3: number): boolean {
if (s1 < 0 || s2 < 0 || s3 < 0) {
return false;
}
return s1 + s2 > s3 && s1 + s3 > s2 && s2 + s3 > s1;
}
isEquilateralTriangle(): boolean {
return this.side1 == this.side2 && this.side2 == this.side3;
}
}
function method_static_ex2_test() {
var valid = Triangle.isValidSides(6, 8, 10);
console.log(`Are sides 6, 8 and 10 valid to make a triangle? ${valid}`);
var triangle = new Triangle(3.0, 4.0, 5.0);
// Check if the triangle is equilateral triangle.
var check = triangle.isEquilateralTriangle();
console.log(`Is Equilateral Triangle? ${check}`);
}
method_static_ex2_test(); // Call the method.
Output:
Are sides 6, 8 and 10 valid to make a triangle? true
Is Equilateral Triangle? false
4. Абстрактный метод
На языке TypeScript абстрактный метод является нестатическим методом и не имеет содержимого.
[protected | public] abstract method_name(arguments) : return_type;
Класс, имеющий по крайней мере один абстрактный метод, должен быть объявлен абстрактным, и один из его подклассов должен переопределять (override) эти абстрактные методы и писать для них содержимое.
method_abstract_ex1.ts
abstract class Person {
abstract sayHello(): void; // An abstract method.
}
class EnglishPerson extends Person {
sayHello(): void {
console.log("Hello");
}
}
class RussianPerson extends Person {
sayHello(): void {
console.log("Привет");
}
}
function method_abstract_ex1_test() {
var enPerson = new EnglishPerson();
enPerson.sayHello();
var ruPerson = new RussianPerson();
ruPerson.sayHello();
}
method_abstract_ex1_test(); // Call the function.
Output:
Hello
Привет
- TypeScript Classes
5. опциональные параметры
Как упоминалось выше, классы в TypeScript и JavaScript не допускают методов с одинаковыми именами, но метод может включать опциональные параметры.
Синтаксис:
// Non-static method with optional arguments:
[private | protected | public] method_name(args, optional_args?): return_type {
// statement(s)
}
// Static method with optional arguments:
[private | protected | public] static method_name(args, optional_args?) : return_type {
// statement(s)
}
// Abstract method with optional arguments:
[protected | public] abstract method_name(args, optional_args?): return_type;
Например:
method_optional_args_ex1.js
class MyUtils {
static concat(s1: string, s2: string, s3?: string): string {
if (s3) {
return s1 + s2 + s3;
}
return s1 + s2;
}
static sum(v1: number, v2: number, v3?: number, v4?: number): number {
return v1 + v2 + (v3 ?? 0) + (v4 ?? 0);
}
}
function method_optional_args_ex1_test() {
var result1 = MyUtils.concat('One', 'Two');
console.log(`result1: ${result1}`);
var result2 = MyUtils.concat('One', 'Two', 'Three');
console.log(`result2: ${result2}`);
var value1 = MyUtils.sum(1, 2, 3, 4);
console.log(`value1: ${value1}`);
var value2 = MyUtils.sum(1, 2, 3);
console.log(`value2: ${value2}`);
var value3 = MyUtils.sum(1, 2);
console.log(`value3: ${value3}`);
}
method_optional_args_ex1_test(); // Call the method.
Output:
result1: OneTwo
result2: OneTwoThree
value1: 10
value2: 6
value3: 3
6. Параметры со значениями по умолчанию
TypeScript поддерживает методы с параметрами по умолчанию, которые должны быть последними параметрами в списке параметров.
Синтаксис:
// Non-static method
[private | protected | public ] method_name (
arg1 : data_type1, arg2 : data_type2,
arg3 : data_type3 = defaultValue3,
arg4 : data_type4 = defaultValue4) : return_type {
// statement(s)
}
// Static method
[private | protected | public ] static method_name (
arg1 : data_type1, arg2 : data_type2,
arg3 : data_type3 = defaultValue3,
arg4 : data_type4 = defaultValue4) : return_type {
// statement(s)
}
// Abstract method
[protected | public ] abstract method_name (
arg1 : data_type1, arg2 : data_type2,
arg3 : data_type3 = defaultValue3,
arg4 : data_type4 = defaultValue4) : return_type;
Например:
method_default_value_args_ex1.ts
class SalesUtils {
static applyDiscount(amount : number, discount: number = 0.05) : number {
return amount * (1 - discount);
}
}
function method_default_value_args_ex1_test() {
var value1 = SalesUtils.applyDiscount(1000);
console.log(`value1 = ${value1}`);
var value2 = SalesUtils.applyDiscount(1000, 0.5);
console.log(`value2 = ${value2}`);
}
method_default_value_args_ex1_test(); // Call the method.
Output:
value1 = 950
value2 = 500
7. Параметры с типом данных объединения
Параметр в методе также может быть объявлен с типом данных объединения (union data type).
// Non-static method
[private | protected | public ] method_name (
arg1 : data_type1, arg2 : data_type2,
arg3 : data_type31 | data_type32 | data_type3N, // Union Data Type
arg4 : data_type4 = defaultValue4) : return_type {
// Statament(s)
}
// Static method
[private | protected | public ] static method_name (
arg1 : data_type1, arg2 : data_type2,
arg3 : data_type31 | data_type32 | data_type3N, // Union Data Type
arg4 : data_type4) : return_type {
// Statament(s)
}
// Abstract method
[protected | public ] abstract method_name (
arg1 : data_type1, arg2 : data_type2,
arg3 : data_type31 | data_type32 | data_type3N, // Union Data Type
arg4 : data_type4) : return_type;
Например:
method_union_type_args_ex1.ts
interface IStudent {
studentId: number,
studentName: string
}
interface IWorker {
workerId: number,
workerName: string
}
class AppUtils {
static getName(person: IStudent | IWorker): string { // Union Type Arg
var p = person as IStudent;
if (p.studentName) {
return p.studentName;
}
return (person as IWorker).workerName;
}
}
function method_union_type_args_ex1_test() {
var student = { studentId: 1, studentName: "Tom" };
var worker = { workerId: 2, workerName: "Jerry" };
var name1 = AppUtils.getName(student);
var name2 = AppUtils.getName(worker);
console.log(`name1: ${name1}`);
console.log(`name2: ${name2}`);
}
method_union_type_args_ex1_test(); // Call the method.
Output:
name1: Tom
name2: Jerry
8. Переопределение метода
Подкласс может переопределять (override) метод родительского класса, если выполняются следующие условия:
- Два метода должны иметь одинаковое имя и одинаковые параметры.
- Тип возвращаемого значения двух методов должен быть одинаковым, или тип возвращаемого значения метода в подклассе должен быть подтипом типа возвращаемого значения метода в родительском классе.
Например:
- Класс Mouse переопределяет (override) метод sayAnything() класса Animal.
method_override_ex1.ts
class Animal {
sayAnything(): void {
console.log('<Nothing>');
}
}
class Mouse extends Animal {
sayAnything(): void { // Override method of parent class.
console.log('Hi Tom!');
}
}
function method_override_ex1_test() {
var animal = new Mouse();
animal.sayAnything(); // Hi Tom!
}
method_override_ex1_test(); // Call the function.
Output:
Hi Tom!
Например: Вы также можете использовать ключевое слово super для вызова метода с тем же именем родительского класса.
method_override_ex2.ts
class BoldFormatter {
formatText(text: string): string {
return '<b>' + text + '</b>';
}
}
class BoldItalicFormatter extends BoldFormatter {
formatText(text: string): string { // Override method of parent class.
var boldText = super.formatText(text); // Call super method.
return '<i>' + boldText + '</i>';
}
}
function method_override_ex2_test() {
var formatter = new BoldItalicFormatter();
var formattedText = formatter.formatText('Hello');
console.log(formattedText);
}
method_override_ex2_test(); // Call the method.
Output:
<i><b>Hello</b></i>
9. Method Overloading
В статье о функциях в TypeScript я представил "Function Overloading" (Перегрузку функций). Метод рассматривается как функция класса, поэтому он также имеет аналогичную концепцию, которая называется "Method Overloading" (Перегрузка метода).
TypeScript не допускает двух методов с одинаковым именем в классе, даже если они имеют разные параметры. Method Overloading позволяет определить метод с различными типами параметров.
В TypeScript, Method Overloading выглядит иначе, чем в C++, Java или C#. Основная идея перегрузки (overload) для метода заключается в создании универсального метода, который проверяет, какой тип параметра был передан при вызове метода, а затем выполняет некоторую логику для соответствующего случая. Полезно добавить определения для метода, чтобы помочь другим программистам узнать, как его правильно использовать.
Синтаксис:
// Definition 1
[static] method_name(arg_11 : type_11, arg_1N : type_1N): return_type;
]// Definition 2
[static] method_name(arg_21 : type_21, arg_22 : type_22, arg_2M : type_2M) : return_type;
[static] method_name(... args : any[]) : return_type {
// Method body.
}
Например:
method_overloading_ex1.ts
interface IDimension {
width: number,
height: number
}
class MathUtils {
static getArea(dimension: IDimension): number; // Definition 1
static getArea(width: number): number; // Definition 2
static getArea(width: number, height: number): number; // Definition 3
static getArea(...args: any[]): number {
if (args.length == 1) {
if (typeof args[0] == 'number') { // Use Definition 2
return args[0] * args[0];
} else { // Use Definition 1
var dim = args[0] as IDimension;
return dim.width * dim.height;
}
} else if (args.length == 2) {
return args[0] * args[1];
} else {
throw new Error('Arguments Invalid!');
}
}
}
function method_overloading_ex1_test() {
var area1 = MathUtils.getArea({ width: 10, height: 20 }); // 200
var area2 = MathUtils.getArea(10); // 100
var area3 = MathUtils.getArea(10, 15); // 150
console.log(`area1: ${area1}`);
console.log(`area2: ${area2}`);
console.log(`area3: ${area3}`);
}
method_overloading_ex1_test(); // Call the function.
Output:
area1: 200
area2: 100
area3: 150
Pуководства TypeScript
- Запустите свой первый пример TypeScript в Visual Studio Code
- Оператор typeof в TypeScript
- Циклы в TypeScript
- Установите TypeScript в Windows
- Функции в TypeScript
- Кортежи (Tuple) в TypeScript
- Интерфейсы в TypeScript
- Массивы в TypeScript
- Оператор instanceof в TypeScript
- Методы в TypeScript
- Замыкания (Closure) в TypeScript
- Конструкторы в TypeScript
- Свойства в TypeScript
Show More