- Chinese version of TypeScript Tutorial – Project introduction
- TypeScript Tutorial Chinese version – Section 0. preface
- TypeScript Tutorial Chinese version – Section 1. An introduction to
- TypeScript Tutorial Chinese version – Section 2. Basic types of
- TypeScript Tutorial Chinese version – Section 3. Control flow statement
- TypeScript Tutorial Chinese – Section 4. function
- TypeScript Tutorial Chinese version – Section 5. class
- TypeScript Tutorial Chinese version – Section 6. interface
- TypeScript Tutorial Chinese version – Section 7. High-level types
- TypeScript Tutorial Chinese version – Section 8. The generic
- TypeScript Tutorial Chinese version – Section 9. The module
- Chinese version of TypeScript Tutorial – Section 10.node.js
Section 5. Class
class
The original address
In this tutorial, you’ll learn about classes in TypeScript.
Introduction to classes in TypeScript
Unlike other programming languages, such as Java and C#, JavaScript has the concept of a class, and in ES5 you can create a “class” through constructors and stereotype inheritance. For example, to create a Person class with SSN, firstName, and lastName attributes, you could use the following constructor:
function Person(ssn, firstName, lastName) {
this.ssn = ssn;
this.firstName = firstName;
this.lastName = lastName;
}
Copy the code
Next, define a prototype method to get the full name of the person by concatenating the values of the firstName and lastName attributes:
Person.prototype.getFullName = function () {
return `The ${this.firstName} The ${this.lastName}`;
};
Copy the code
You can then create a new object from the Person “class” :
let person = new Person('171-28-0926'.'John'.'Doe');
console.log(person.getFullName());
Copy the code
It prints the following message on the console:
John Doe
Copy the code
ES6 allows you to define a class that is the syntactic sugar for creating the corresponding constructor and stereotype inheritance:
class Person {
ssn;
firstName;
lastName;
constructor(ssn, firstName, lastName) {
this.ssn = ssn;
this.firstName = firstName;
this.lastName = lastName; }}Copy the code
In the syntax of the class above, the constructor is already explicitly defined in the class. Next add the getFullName() method:
class Person {
ssn;
firstName;
lastName;
constructor(ssn, firstName, lastName) {
this.ssn = ssn;
this.firstName = firstName;
this.lastName = lastName;
}
getFullName() {
return `The ${this.firstName} The ${this.lastName}`; }}Copy the code
The object created using the Person class is the same as the object created using the Person constructor:
let person = new Person('171-28-0926'.'John'.'Doe');
console.log(person.getFullName());
Copy the code
Classes in TypeScript add type annotations to their properties and methods. Here’s how to use the Person class in TypeScript:
class Person {
ssn: string;
firstName: string;
lastName: string;
constructor(ssn: string, firstName: string, lastName: string) {
this.ssn = ssn;
this.firstName = firstName;
this.lastName = lastName;
}
getFullName(): string {
return `The ${this.firstName} The ${this.lastName}`; }}Copy the code
When you add type annotations to class properties, constructors, and methods, the TypeScript compiler does type checking. For example, you cannot initialize SSN as a value of type number. The following code will throw an error:
let person = new Person(171280926.'John'.'Doe');
Copy the code
summary
- Used in TypeScript
class
Keyword definition class; - TypeScript adds type annotations to the syntax of ES6 classes to make them more robust to use.
Access modifier
The original address
In this tutorial, you’ll learn about access modifiers in TypeScript.
Access modifiers change the visibility of properties and methods in a class. TypeScript provides three access modifiers:
private
protected
public
Note that TypeScript controls the visibility of properties and methods at compile time, not at run time.
Private modifiers
Private modifiers restrict properties and methods to being visible only in the current class. This means that when you add a private modifier to a method or property, it can only be accessed in the current class. Accessing private properties and methods outside the current class will raise an error at compile time.
The following example shows how to add the private modifier to the SNN, firstName, and lastName attributes of the Person class:
class Person {
private ssn: string;
private firstName: string;
private lastName: string;
// ...
}
Copy the code
With the private modifier, you can access the SSN attribute in a constructor or Person class method, such as:
class Person {
private ssn: string;
private firstName: string;
private lastName: string;
constructor(ssn: string, firstName: string, lastName: string) {
this.ssn = ssn;
this.firstName = firstName;
this.lastName = lastName;
}
getFullName(): string {
return `The ${this.firstName} The ${this.lastName}`; }}Copy the code
Try accessing the SSN attribute outside of the Person class:
let person = new Person('the 153-07-31 30'.'John'.'Doe');
console.log(person.ssn); // compile error
Copy the code
The public modifier
The public modifier allows class properties and methods to be accessed from anywhere. If no modifier is specified for the properties and methods, the default is the public modifier.
Add the public modifier to the getFullName() method in the Person class as shown below:
class Person {
// ...
public getFullName(): string {
return `The ${this.firstName} The ${this.lastName}`;
}
// ...
}
Copy the code
It has the same effect as omitting the public keyword.
Protected modifier
The protected modifier allows the properties and methods of a class to be accessed within the current class or a subclass of the current class. When a class (subclass) inherits from another class (parent class), it is a subclass of the parent class. If you try to access protected properties from anywhere else, the TypeScript compiler will throw an error.
Add protected modifiers to methods and properties using the protected keyword, as follows:
class Person {
protected ssn: string;
// other code
}
Copy the code
The SSN attribute is now protected, accessible in the Person class and any subclasses that inherit the Person class, and you can learn more about inheritance from class inheritance.
The Person class declares two private and one protected properties, and the constructor initializes them with the three parameters it receives.
To make your code look simpler, TypeScript allows you to declare and initialize properties at the same time in constructors, like this:
class Person {
constructor(
protected ssn: string.private firstName: string.private lastName: string.) {
this.ssn = ssn;
this.firstName = firstName;
this.lastName = lastName;
}
getFullName(): string {
return `The ${this.firstName} The ${this.lastName}`; }}Copy the code
When you consider the visibility of properties and methods, it is best to give them the lowest visibility access modifier, the private modifier.
summary
- TypeScript provides three access modifiers for properties and methods:
private
.protected
和public
The modifier; private
Modifiers are accessible only in the current class;protected
Modifiers allow access in the current class and subclasses of the current class;public
Modifiers can be accessed anywhere.
Read-only property
The original address
In this tutorial, you’ll learn how to use TypeScript read-only access modifiers, which mark class properties as immutable.
TypeScript provides read-only access modifiers that allow you to mark class properties as immutable. You can only add read-only attributes to attributes in one of two places:
- Where attributes are defined;
- Constructor of the current class.
To mark an attribute as immutable, you need to use the readonly keyword. Here’s how to declare a read-only attribute in the Person class:
class Person {
readonly birthDate: Date;
constructor(birthDate: Date) {
this.birthDate = birthDate; }}Copy the code
In this case, birthDate is a read-only property that is initialized in the constructor of the Person class. Try reassigning the birthDate attribute and throw an error message like the following:
let person = new Person(new Date(1990.12.25));
person.birthDate = new Date(1991.12.25); // Compile error
Copy the code
Like other access modifiers, you can declare and initialize read-only properties in the constructor, as follows:
class Person {
constructor(readonly birthDate: Date) {
this.birthDate = birthDate; }}Copy the code
Readonly vs const
Here are the differences between readonly and const:
readonly |
const |
|
---|---|---|
Used for | Attributes of a class | variable |
Initialize the | When a property is declared or in the current class constructor | When you declare variables |
summary
- Use read-only access modifiers to mark class attributes as immutable;
- Read-only access modifications must be initialized at the time the property is declared or in the current class constructor.
Getter / Setter
The original address
In this tutorial, you’ll learn how to use getters and setters in TypeScript.
An introduction to getter and setter methods in TypeScript
Here is a simple Person class with only three attributes: Age, firstName, and lastName.
class Person {
public age: number;
public firstName: string;
public lastName: string;
}
Copy the code
To access the attributes of the Person class, do this:
let person = new Person();
person.age = 26;
Copy the code
Suppose you assign a value from user input to the age property:
person.age = inputAge;
Copy the code
The inputAge variable can be any number, and can be checked before assigning to be valid for age:
if (inputAge > 0 && inputAge < 200) {
person.age = inputAge;
}
Copy the code
But using this check statement everywhere is redundant and tedious. To avoid double checking, you can use getter and setter methods, which control how class attributes are accessed. For each attribute:
getter
Method returns the value of the property,getter
Methods are also known asaccessor
Methods;setter
Method updates the value of the property,setter
Methods are also known asmutator
Methods.
Getter methods begin with the get keyword, while setter methods begin with the set keyword:
class Person {
private _age: number;
private _firstName: string;
private _lastName: string;
// We didn't write the constructor function in TypeScript
constructor(age: number, firstName: string, lastName: string) {
this._age = age;
this._firstName = firstName;
this._lastName = lastName;
}
public get age() {
return this._age;
}
public set age(theAge: number) {
if (theAge <= 0 || theAge >= 200) {
throw new Error('The age is invalid');
}
this._age = theAge;
}
public getFullName(): string {
return `The ${this._firstName} The ${this._lastName}`; }}Copy the code
Here’s how it works:
- First, the
age
.firstName
和lastName
Property from the access modifierpublic
Change toprivate
; - Next, let’s put
age
Property changed to_age
; - The third,
_age
Attribute to addgetter
和setter
Methods,setter
In the user input age variable value assigned to_age
Property, check if the variable value is valid.
Now, you can access the setter method of age as follows:
let person = new Person();
person.age = 10;
Copy the code
Notice that calling setter methods does not have parentheses in the method name, as regular method calls do. When you call Person. age, the setter method for age is called. If you set an invalid age value, the setter method throws an error message:
person.age = 0;
Copy the code
Error message:
Error: The age is invalid
Copy the code
When you access Person. age, the age getter is called:
console.log(person.age);
Copy the code
Here we add getter and setter methods to firstName and lastName attributes:
class Person {
private _age: number;
private _firstName: string;
private _lastName: string;
// We didn't write the constructor function in TypeScript
constructor(age: number, firstName: string, lastName: string) {
this._age = age;
this._firstName = firstName;
this._lastName = lastName;
}
public get age() {
return this._age;
}
public set age(theAge: number) {
if (theAge <= 0 || theAge >= 200) {
throw new Error('The age is invalid');
}
this._age = theAge;
}
public get firstName() {
return this._firstName;
}
public set firstName(theFirstName: string) {
if(! theFirstName) {throw new Error('Invalid first name.');
}
this._firstName = theFirstName;
}
public get lastName() {
return this._lastName;
}
public set lastName(theLastName: string) {
if(! theLastName) {throw new Error('Invalid last name.');
}
this._lastName = theLastName;
}
public getFullName(): string {
return `The ${this.firstName} The ${this.lastName}`; }}Copy the code
More getter/setter methods examples
As you can see from the code, it is very useful to use setter methods to validate data before assigning values to properties, and you can do other complex logic as well.
Here’s how to create getter and setter methods for fullName:
class Person {
// ... other code
public get fullName() {
return `The ${this.firstName} The ${this.lastName}`;
}
public set fullName(name: string) {
let parts = name.split(' ');
if(parts.length ! =2) {
throw new Error('Invalid name format: first last');
}
this.firstName = parts[0];
this.lastName = parts[1]; }}Copy the code
Here’s how it works:
getter
Method returnsfirstName
和lastName
Concatenated string;setter
Method accepts a string asfullName
Variable, which has the following format: The first part of the string is assigned tofirstName
Property, the second part of the string is assigned tolastName
Properties.
Now you can access the setter and getter properties of fullName just like a normal class property:
let person = new Person();
person.fullname = 'John Doe';
console.log(person.fullName);
Copy the code
summary
- Use TypeScript
getter
/setter
Method to control how class attributes are accessed; getter
/setter
Methods are also known asaccessor
/mutator
Methods.
Class inheritance
The original address
In this tutorial, you’ll learn about the concept of inheritance in TypeScript and how to use it to override the functionality of other classes.
Introduction to inheritance in TypeScript
A class can have its properties and methods reused by other classes, which in TypeScript is called inheritance. Classes that inherit the properties and methods of other classes are called subclasses, and inherited classes are called parent classes. These names come from the way in nature that children inherit their parents’ genes. Inheritance lets you reuse the functionality of existing classes without having to rewrite them all over again.
JavaScript implements classes using archetypal inheritance rather than Java and C# class inheritance. The class syntax introduced in ES6 is the syntactic sugar of JavaScript archetypal inheritance, and TypeScript also supports it.
Suppose we have the following Person class:
class Person {
constructor(private firstName: string.private lastName: string) {
this.firstName = firstName;
this.lastName = lastName;
}
getFullName(): string {
return `The ${this.firstName} The ${this.lastName}`;
}
describe(): string {
return `This is The ${this.firstName} The ${this.lastName}. `; }}Copy the code
Use the extends keyword to extend other classes. For example, the following Employee class extends from the Person class:
class Employee extends Person {
/ /..
}
Copy the code
In this example, Employee is a subclass and Person is the parent class.
The constructor
Because the Person class has a constructor that initializes firstName and lastName attributes, you need to call the parent constructor in the Employee constructor to initialize these attributes. To call the parent class’s constructor in a subclass’s constructor, use the super() syntax:
class Employee extends Person {
constructor(firstName: string, lastName: string.private jobTitle: string) {
// call the constructor of the Person class:
super(firstName, lastName);
this.jobTitle = jobTitle; }}Copy the code
Here we create an instance of the Employee class:
let employee = new Employee('John'.'Doe'.'Front-end Developer');
Copy the code
Because the Employee class inherits the methods and attributes of the Person class, you can call the getFullName() and describe() methods on the Employee object, as follows:
let employee = new Employee('John'.'Doe'.'Web Developer');
console.log(employee.getFullName());
console.log(employee.describe());
Copy the code
Output:
John Doe
This is John Doe.
Copy the code
Method overloading
When you call the Employee.describe () method on the Employee object, the Describe () method of the Person class is executed, displaying This is John Doe information. If the Employee class wants to have its own describe() method, you can define the Describe () method in the Employee class, as follows:
class Employee extends Person {
constructor(firstName: string, lastName: string.private jobTitle: string) {
super(firstName, lastName);
this.jobTitle = jobTitle;
}
describe(): string {
return super.describe() + `I'm a The ${this.jobTitle}. `; }}Copy the code
In the describe () method, we use super. MethodInParentClass () syntax to invoke the describe of the parent () method. If you call the describe() method on an Employee object, the describe() method of the Employee class will be called:
let employee = new Employee('John'.'Doe'.'Web Developer');
console.log(employee.describe());
Copy the code
Output:
This is John Doe.I'm a Web Developer.
Copy the code
summary
- use
extends
Keywords allow one class to inherit from another; - Used in the constructor of a subclass
super
Method calls the parent class’s constructor, used in a subclass’s methodsuper.methodInParentClass()
The syntax calls the parent classmethodInParentClass()
Methods.
Static properties and methods
The original address
In this tutorial, you’ll learn about static properties and methods in TypeScript.
Static attributes
Unlike instance properties, static properties are shared between all instances of a class. To declare static properties, use the static keyword, and to access static properties, use the classname.propertyName syntax, as follows:
class Employee {
static headcount: number = 0;
constructor(
private firstName: string.private lastName: string.private jobTitle: string.){ Employee.headcount++; }}Copy the code
In this case, headCount is a static property with an initial value of 0, which is incremented by one each time a new instance is created. The following example creates two Employee instances that print the value of the headCount property and return the expected 2:
let john = new Employee('John'.'Doe'.'Front-end Developer');
let jane = new Employee('Jane'.'Doe'.'Back-end Developer');
console.log(Employee.headcount); / / 2
Copy the code
A static method
Static methods, like static properties, are shared between all instances of the class. To declare a static method, add the static keyword to the name of the method, as shown below:
class Employee {
private static headcount: number = 0;
constructor(
private firstName: string.private lastName: string.private jobTitle: string.) {
Employee.headcount++;
}
public static getHeadcount() {
returnEmployee.headcount; }}Copy the code
In this example:
- First of all,
headcount
Static property access modifiers frompublic
Change toprivate
, so that its value cannot be changed outside the class unless a new one is createdEmployee
Instance; - Then, add
getHeadcount()
Static method that returnsheadcount
The value of a static property.
You can use the syntax classname.staticmethod () to call a staticMethod, as follows:
let john = new Employee('John'.'Doe'.'Front-end Developer');
let jane = new Employee('Jane'.'Doe'.'Back-end Developer');
console.log(Employee.getHeadcount); / / 2
Copy the code
In fact, you’ll find that Math objects have lots of static properties and methods, such as static properties for PI and E, static methods for abs() and round(), etc.
summary
- Static properties and methods are shared between all instances of a class;
- To be added before a property or method name
static
Keyword that can be made a static property or a static method.
Abstract methods
The original address
In this tutorial, you’ll learn about abstract classes in TypeScript.
Introduction to abstract classes in TypeScript
Abstract classes are usually used to define the common behavior of derived classes to be extended, and unlike regular classes, abstract classes cannot be instantiated directly. To declare an abstract class, use the abstract keyword:
abstract class Employee {
/ /...
}
Copy the code
Typically, an abstract class contains one or more abstract methods. An abstract method contains no concrete implementation; it defines only the signature of the method, not the method body, whereas an abstract method must be implemented in a derived class.
Here is an abstract Employee class with the getSalary() abstract method:
abstract class Employee {
constructor(private firstName: string.private lastName: string) {}
abstract getSalary(): number;
get fullName() :string {
return `The ${this.firstName} The ${this.lastName}`;
}
compensationStatement(): string {
return `The ${this.fullName} makes The ${this.getSalary()} a month.`; }}Copy the code
In the Employee class:
- The constructor is declared
firstName
和lastName
Properties; getSalary()
A method is an abstract method, and a derived class implements concrete logic based on the employee’s type;getFullName()
和compensationStatement()
Methods have concrete implementations, notecompensationStatement()
Method will callgetSalary()
Methods.
Because Employee is an abstract class and cannot be used to create an instance, the following statement throws an error:
let employee = new Employee('John'.'Doe');
Copy the code
Error message:
error TS2511: Cannot create an instance of an abstract class.
Copy the code
The following FullTimeEmployee class inherits the Employee abstract class:
class FullTimeEmployee extends Employee {
constructor(firstName: string, lastName: string.private salary: number) {
super(firstName, lastName);
}
getSalary(): number {
return this.salary; }}Copy the code
In the FullTimeEmployee class, the constructor defines the salary attribute. Because getSalary() is an abstract method of Employee, FullTimeEmployee needs to implement this method. In this case, the method does nothing and returns the value of the salary variable to represent the value of the salary.
The following Contractor class inherits the Employee abstract class:
class Contractor extends Employee {
constructor(
firstName: string,
lastName: string.private rate: number.private hours: number.) {
super(firstName, lastName);
}
getSalary(): number {
return this.rate * this.hours; }}Copy the code
In the Contractor class, the constructor defines the rate and hours properties, and the getSalary() method multiplies the rate and hours to show the value of the reward.
The following example creates an instance of the FullTimeEmployee class and an instance of the Contractor class, and displays their compensation information on the console:
let john = new FullTimeEmployee('John'.'Doe'.12000);
let jane = new Contractor('Jane'.'Doe'.100.160);
console.log(john.compensationStatement());
console.log(jane.compensationStatement());
Copy the code
Output:
John Doe makes 12000 a month.
Jane Doe makes 16000 a month.
Copy the code
When you want to share code between classes that are related to each other, using abstract classes is a good way to do it.
summary
- Abstract classes cannot be instantiated;
- An abstract class has at least one abstract method;
- When you use an abstract class, you need to inherit it and implement all the abstract methods in the class.