TypeScript 第九节:类
?一、类
TypeScript 类是面向对象编程中的一个概念,它是一种模板或蓝图,用于创建具有相同属性和方法的对象。 类可以看作是对象的模板,定义了对象的属性和方法。
TypeScript的类和ES6的类类似,但它提供了更多的特性和类型检查。类可以包含属性和方法。 属性是类中存储的数据,而方法定义了类可以执行的操作。类还可以具有构造函数,用于在创建对象时初始化类的属性。
1、基本语法:定义一个类
class Person {
   // 成员变量
   name: string;
   age: number;
   
   // 构造函数
   constructor(name: string, age: number) {
      this.name = name;
      this.age = age;
   }
   
   // 成员函数
   getInfo(): string {
      return `Name: ${this.name}, Age: ${this.age}`;
   }
}
 
这个类包含了一个构造函数和一个成员函数
getInfo(),并且定义了两个成员变量name和age。可以通过实例化这个类来创建一个对象:const person = new Person("Alice", 30); console.log(person.getInfo()); // 输出 "Name: Alice, Age: 30"
?2、类的继承
在 TypeScript 中,我们可以使用关键字
extends实现类的继承。子类可以继承父类的属性和方法,并且可以在子类中添加新的属性和方法或覆盖父类的属性和方法。
下面是一个示例:
class Animal {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
  move(distanceInMeters: number = 0) {
    console.log(`${this.name} moved ${distanceInMeters}m.`);
  }
}
class Dog extends Animal {
  constructor(name: string) {
    super(name);
  }
  bark() {
    console.log('Woof! Woof!');
  }
}
const dog = new Dog('Rufus');
dog.bark();  // Output: "Woof! Woof!"
dog.move(10);  // Output: "Rufus moved 10m."
 
在上面的示例中,
Dog继承自Animal。Dog类有一个新的方法bark,同时还继承了Animal中的name和move方法。在子类的构造函数中,我们使用super调用父类的构造函数,以便在子类中使用父类中的属性。
3、继承类的方法重写
在 TypeScript 中,可以通过继承和方法重写来实现类的扩展和定制化。
具体步骤如下:
第一步、定义父类
定义一个父类,其中包含需要被继承和重写的属性和方法。
class Animal {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
  speak() {
    console.log(`${this.name} makes a noise.`);
  }
}
 
 
第二步、定义子类并继承父类
定义一个子类,并使用
extends关键字继承父类。
class Dog extends Animal {
  breed: string;
  constructor(name: string, breed: string) {
    super(name);
    this.breed = breed;
  }
  speak() {
    console.log(`${this.name} barks.`);
  }
}
 
 
第三步、重写父类方法
在子类中重写父类的方法,使用与父类方法名相同的方法名,并在方法体中实现需要的逻辑。
class Dog extends Animal {
  breed: string;
  constructor(name: string, breed: string) {
    super(name);
    this.breed = breed;
  }
  speak() {
    console.log(`${this.name} barks.`);
  }
}
 
 
示例代码如下:
class Animal {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
  speak() {
    console.log(`${this.name} makes a noise.`);
  }
}
class Dog extends Animal {
  breed: string;
  constructor(name: string, breed: string) {
    super(name);
    this.breed = breed;
  }
  speak() {
    console.log(`${this.name} barks.`);
  }
}
const animal = new Animal('Animal');
const dog = new Dog('Buddy', 'Golden Retriever');
animal.speak(); // Animal makes a noise.
dog.speak(); // Buddy barks.
 
在上面的示例中,子类
Dog继承了父类Animal,并重写了speak方法。当我们创建一个Animal实例并调用speak方法时,输出的是父类的默认实现。当我们创建一个Dog实例并调用speak方法时,输出的是子类中重写的实现。
?
4、static 关键字?
static 关键字用于定义类的数据成员(属性和方法)为静态的,静态成员可以直接通过类名调用。
class StaticMem {  
   static num:number; 
   
   static disp():void { 
      console.log("num 值为 "+ StaticMem.num) 
   } 
} 
 
StaticMem.num = 12     // 初始化静态变量
StaticMem.disp()       // 调用静态方法 
?
5、?访问控制修饰符
TypeScript 有三个访问控制修饰符:public、private 和 protected。
5.1、public(公共访问控制符)
public 是默认的访问修饰符,表示该成员可以被任何代码访问。可以省略不写。
5.2、private(私有访问控制符)
private 表示该成员只能被类内部的代码访问,无法被类外部的代码访问。
class Person {
  private name: string;
  constructor(name: string) {
    this.name = name;
  }
  public getname(): string {
    // 可以访问私有成员
    return this.name;
  }
}
const person = new Person('John');
console.log(person.name); // 编译错误,无法访问私有成员
console.log(person.getname()); // John
 
5.3、protected (保护访问控制符)
protected 表示该成员可以被类内部和子类的代码访问,但是无法被类外部的代码访问。
class Person {
  protected name: string;
  constructor(name: string) {
    this.name = name;
  }
  public getname(): string {
    // 可以访问受保护的成员
    return this.name;
  }
}
class Student extends Person {
  constructor(name: string) {
    super(name);
  }
  public getStudentName(): string {
    // 可以访问父类的受保护成员
    return this.name;
  }
}
const person = new Person('John');
console.log(person.name); // 编译错误,无法访问受保护的成员
console.log(person.getname()); // John
const student = new Student('Amy');
console.log(student.getname()); // 编译错误,无法访问受保护的成员
console.log(student.getStudentName()); // Amy
 
 
6、类和接口
在 TypeScript 中,可以使用接口来定义类的结构。使用接口来定义类的结构,可以让代码更加清晰和易于维护。
下面是一个使用接口来定义类的例子:
interface Person {
  name: string;
  age: number;
  sayHello: () => void;
}
class Student implements Person {
  name: string;
  age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
  sayHello() {
    console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old.`);
  }
}
const student = new Student('Bob', 20);
student.sayHello(); // Output: Hello, my name is Bob and I'm 20 years old.
 
在上面的代码中,我们使用接口
Person来定义了一个人的结构,其中包括name和age两个属性,以及一个sayHello方法。然后我们定义了一个Student类,这个类实现了Person接口,即Student类必须满足Person接口中定义的结构。最后我们创建了一个Student类型的实例student,并调用了它的sayHello方法。使用接口来定义类的结构,可以让我们更加灵活地维护代码,因为只要符合接口定义的结构,就可以被赋值给接口类型的变量。这样也可以降低代码的耦合度,增加代码的可维护性。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!