Question d'entretien-TS(4) : Comment utiliser les classes et l'héritage dans TypeScript ?
Dans TypeScript, les classes sont un concept important qui nous permet d'organiser et de gérer le code en utilisant un style de programmation orienté objet. Les classes fournissent un modèle pour créer des objets avec des propriétés et des comportements identiques. Grâce à l'héritage, nous pouvons créer une hiérarchie entre les classes pour réaliser la réutilisation et l'extension du code.
1. Définition et utilisation des classes
Dans TypeScript, nous utilisons class
des mots-clés pour définir des classes. Voici un exemple de classe simple :
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
greet(): void {
console.log(`Hello, my name is ${
this.name}. I'm ${
this.age} years old.`);
}
}
Dans l'exemple ci-dessus, nous avons défini une Person
classe appelée , qui a des propriétés name
et age
, et une greet
méthode. Les constructeurs sont utilisés pour initialiser les propriétés d'un objet.
Créer une instance d'une classe est aussi simple que d'utiliser new
le mot-clé plus le constructeur de la classe :
let person = new Person("John", 25);
person.greet(); // 输出:Hello, my name is John. I'm 25 years old.
Grâce à la définition de classe, nous pouvons créer plusieurs objets avec les mêmes attributs et comportements pour réaliser la réutilisation et l'encapsulation du code.
2. Héritage et sous-classement
En programmation orientée objet, l'héritage est un concept important. Grâce à l'héritage, nous pouvons créer une sous-classe (également appelée classe dérivée) d'une classe et hériter de ses propriétés et méthodes. Les sous-classes peuvent étendre ou modifier les fonctions de la classe parent, réalisant ainsi la réutilisation et l'extension du code.
Dans TypeScript, nous utilisons extends
des mots clés pour spécifier qu'une classe hérite d'une autre classe. Voici un exemple d'héritage simple :
class Student extends Person {
studentId: string;
constructor(name: string, age: number, studentId: string) {
super(name, age);
this.studentId = studentId;
}
study(): void {
console.log(`Student ${
this.name} is studying with student ID ${
this.studentId}.`);
}
}
Dans l'exemple ci-dessus, nous avons défini une Student
sous-classe nommée , qui hérite de la Person
classe parent. Les sous-classes ont leurs propres attributs studentId
et super
appellent le constructeur de la classe parent en appelant le mot-clé.
La création d'une instance d'une sous-classe est similaire à la création d'une instance de la classe parent :
let student = new Student("Alice", 20, "12345");
student.greet(); // 输出:Hello, my name is Alice. I'm 20 years old.
student.study(); // 输出:Student Alice is studying with student ID 12345.
En héritant et en créant une instance d'une sous-classe, nous pouvons utiliser les propriétés et les méthodes de la classe parente et étendre les fonctions de la sous-classe.
3. Réécriture de méthode
Les sous-classes peuvent remplacer (remplacer) les méthodes de la classe parente pour obtenir des comportements spécifiques. Une implémentation de méthode dans une classe parent peut être remplacée en redéfinissant une méthode dans la sous-classe avec le même nom que la classe parent.
Voici un exemple de redéfinition d'une méthode de classe parent :
class Teacher extends Person {
subject: string;
constructor(name: string, age: number, subject: string) {
super(name, age);
this.subject = subject;
}
greet(): void {
console.log(`Hello, my name is ${
this.name}. I teach ${
this.subject}.`);
}
}
Dans l'exemple ci-dessus, nous avons défini une Teacher
sous-classe nommée , qui hérite de la Person
classe parent et remplace greet
les méthodes de la classe parent. En remplaçant, nous pouvons personnaliser un comportement spécifique dans les sous-classes.
Créez une instance de la sous-classe et appelez la méthode remplacée :
let teacher = new Teacher("Mr. Smith", 35, "Math");
teacher.greet(); // 输出:Hello, my name is Mr. Smith. I teach Math.
En réécrivant la méthode, nous pouvons modifier ou étendre le comportement de la classe mère en fonction des besoins de la sous-classe.
4. Modificateurs d'accès
Dans TypeScript, nous pouvons utiliser des modificateurs d'accès pour restreindre l'accès aux propriétés et aux méthodes d'une classe. Voici quelques modificateurs d'accès couramment utilisés :
public
(par défaut) : accessible à l'intérieur et à l'extérieur de la classe.private
: Accessible uniquement à l'intérieur de la classe.protected
: Peut être consulté à l'intérieur de la classe et dans les sous-classes, mais pas à l'extérieur de la classe.
Par exemple
class Person {
public name: string;
private age: number;
protected gender: string;
constructor(name: string, age: number, gender: string) {
this.name = name;
this.age = age;
this.gender = gender;
}
sayHi() {
console.log(`Hi, my name is ${
this.name}.`);
}
private sayAge() {
console.log(`I am ${
this.age} years old.`);
}
}
class Student extends Person {
constructor(name: string, age: number, gender: string) {
super(name, age, gender);
}
sayGender() {
console.log(`My gender is ${
this.gender}.`);
}
}
let person = new Person("Tom", 18, "male");
console.log(person.name); // "Tom"
console.log(person.age); // Error: Property 'age' is private and only accessible within class 'Person'.
console.log(person.gender); // Error: Property 'gender' is protected and only accessible within class 'Person' and its subclasses.
let student = new Student("Jane", 20, "female");
console.log(student.gender); // "female"
En utilisant des modificateurs d'accès, nous pouvons contrôler la visibilité des membres d'une classe, améliorant ainsi l'encapsulation et la sécurité.
5. Classe abstraite
En TypeScript, nous pouvons également utiliser une classe abstraite pour définir une classe de base non instanciable. Une classe abstraite fournit un modèle pour dériver d'autres classes et définit certaines méthodes abstraites qui doivent être implémentées par des sous-classes. Les classes abstraites ne peuvent pas être instanciées directement, seulement héritées.
Voici un exemple de classe abstraite :
abstract class Shape {
abstract calculateArea(): number;
}
class Rectangle extends Shape {
width: number;
height: number;
constructor(width: number, height: number) {
super();
this.width = width;
this.height = height;
}
calculateArea(): number {
return this.width * this.height;
}
}
Dans l'exemple ci-dessus, nous avons défini une classe abstraite Shape
qui a une méthode abstraite calculateArea
. Les sous-classes Rectangle
héritent des méthodes Shape
et les implémentent calculateArea
.
Grâce aux classes abstraites, nous pouvons définir certains comportements et méthodes de base, et forcer les sous-classes à implémenter ces méthodes, réalisant ainsi la spécification et l'évolutivité du code.
Résumer
L'utilisation des classes et de l'héritage peut rendre notre code plus structuré et lisible, réduire le code répétitif et permettre des applications hautement flexibles et extensibles. Tirer pleinement parti des avantages de la classe et de l'héritage dans TypeScript améliorera l'efficacité de notre développement et la qualité du code.