Pergunta da entrevista-TS(4): Como usar classes e herança no TypeScript?
No TypeScript, as classes são um conceito importante que nos permite organizar e gerenciar o código usando um estilo de programação orientado a objetos. As classes fornecem um modelo para criar objetos com propriedades e comportamentos idênticos. Por meio da herança, podemos criar uma hierarquia entre as classes para alcançar a reutilização e a extensão do código.
1. Definição e uso de classe
No TypeScript, usamos class
palavras-chave para definir classes. Aqui está um exemplo de uma classe simples:
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.`);
}
}
No exemplo acima, definimos uma Person
classe chamada , que possui propriedades name
e age
, e um greet
método. Os construtores são usados para inicializar as propriedades de um objeto.
Criar uma instância de uma classe é tão simples quanto usar new
a palavra-chave mais o construtor da classe:
let person = new Person("John", 25);
person.greet(); // 输出:Hello, my name is John. I'm 25 years old.
Por meio da definição de classe, podemos criar vários objetos com os mesmos atributos e comportamentos para obter a reutilização e o encapsulamento do código.
2. Herança e subclasse
Na programação orientada a objetos, a herança é um conceito importante. Por meio da herança, podemos criar uma subclasse (também conhecida como classe derivada) de uma classe e herdar suas propriedades e métodos. As subclasses podem estender ou modificar as funções da classe pai, realizando assim a reutilização e extensão do código.
No TypeScript, usamos extends
palavras-chave para especificar que uma classe herda de outra classe. Aqui está um exemplo simples de herança:
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}.`);
}
}
No exemplo acima, definimos uma Student
subclasse chamada , que herda da Person
classe pai. As subclasses têm seus próprios atributos studentId
e super
chamam o construtor da classe pai chamando a palavra-chave.
A criação de uma instância de uma subclasse é semelhante à criação de uma instância da classe pai:
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.
Ao herdar e criar uma instância de uma subclasse, podemos usar as propriedades e métodos da classe pai e estender as funções da subclasse.
3. Reescrita do método
As subclasses podem substituir (substituir) os métodos da classe pai para obter comportamentos específicos. Uma implementação de método em uma classe pai pode ser substituída pela redefinição de um método na subclasse com o mesmo nome da classe pai.
Aqui está um exemplo de substituição de um método de classe pai:
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}.`);
}
}
No exemplo acima, definimos uma Teacher
subclasse chamada , que herda da Person
classe pai e substitui greet
os métodos da classe pai. Ao substituir, podemos personalizar um comportamento específico em subclasses.
Crie uma instância da subclasse e chame o método substituído:
let teacher = new Teacher("Mr. Smith", 35, "Math");
teacher.greet(); // 输出:Hello, my name is Mr. Smith. I teach Math.
Ao reescrever o método, podemos modificar ou estender o comportamento da classe pai de acordo com as necessidades da subclasse.
4. Modificadores de acesso
No TypeScript, podemos usar modificadores de acesso para restringir o acesso a propriedades e métodos de uma classe. A seguir estão vários modificadores de acesso comumente usados:
public
(padrão): Pode ser acessado dentro e fora da classe.private
: Só pode ser acessado dentro da classe.protected
: pode ser acessado dentro da classe e em subclasses, mas não fora da classe.
Por exemplo
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"
Ao usar modificadores de acesso, podemos controlar a visibilidade dos membros de uma classe, aprimorando o encapsulamento e a segurança.
5. Aula abstrata
No TypeScript, também podemos usar uma classe abstrata para definir uma classe base não instanciável. Uma classe abstrata fornece um modelo para derivar outras classes e define alguns métodos abstratos que devem ser implementados por subclasses. Classes abstratas não podem ser instanciadas diretamente, apenas herdadas.
Aqui está um exemplo de uma classe abstrata:
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;
}
}
No exemplo acima, definimos uma classe abstrata Shape
que possui um método abstrato calculateArea
. As subclasses Rectangle
herdam Shape
e implementam calculateArea
métodos.
Por meio de classes abstratas, podemos definir alguns comportamentos e métodos básicos e forçar subclasses a implementar esses métodos, obtendo assim especificação de código e escalabilidade.
Resumir
O uso de classes e herança pode tornar nosso código mais estruturado e legível, reduzir o código repetitivo e permitir aplicativos altamente flexíveis e extensíveis. Fazer pleno uso das vantagens de classe e herança em TypeScript melhorará nossa eficiência de desenvolvimento e qualidade de código.