类
类的定义
在面向对象语言中,类是一种面向对象计算机编程语言的构造,是创建对象的蓝图,描述了所创建的对象共同的属性和方法。在 TypeScript 中,我们可以通过 Class 关键字来定义一个类:
class Person {
name!: string; //如果初始属性没赋值就需要加上!
constructor(_name: string) {
this.name = _name;
}
getName(): void {
console.log(this.name);
}
}
let p1 = new Person("hello");
p1.getName();
当然 如果我们图省事 我们也可以把属性定义直接写到构造函数的参数里面去(不过一般不建议这样写 因为会让代码增加阅读难度)
class Person {
constructor(public name: string) {}
getName(): void {
console.log(this.name);
}
}
let p1 = new Person("hello");
p1.getName();
存取器
在 TypeScript 中,我们可以通过存取器来改变一个类中属性的读取和赋值行为
class User {
myname: string;
constructor(myname: string) {
this.myname = myname;
}
get name() {
return this.myname;
}
set name(value) {
this.myname = value;
}
}
let user = new User("hello");
user.name = "world";
console.log(user.name);
readonly 只读属性
readonly 修饰的变量只能在构造函数中初始化 TypeScript 的类型系统同样也允许将 interface、type、 class 上的属性标识为 readonly readonly 实际上只是在编译阶段进行代码检查。
class Animal {
public readonly name: string;
constructor(name: string) {
this.name = name;
}
changeName(name: string) {
this.name = name; //这个ts是报错的
}
}
let a = new Animal("hello");
继承
子类继承父类后子类的实例就拥有了父类中的属性和方法,可以增强代码的可复用性
将子类公用的方法抽象出来放在父类中,自己的特殊逻辑放在子类中重写父类的逻辑
super 可以调用父类上的方法和属性
在 TypeScript 中,我们可以通过 extends 关键字来实现继承
class Person {
name: string; //定义实例的属性,默认省略public修饰符
age: number;
constructor(name: string, age: number) {
//构造函数
this.name = name;
this.age = age;
}
getName(): string {
return this.name;
}
setName(name: string): void {
this.name = name;
}
}
class Student extends Person {
no: number;
constructor(name: string, age: number, no: number) {
super(name, age);
this.no = no;
}
getNo(): number {
return this.no;
}
}
let s1 = new Student("hello", 10, 1);
console.log(s1);
类里面的修饰符
public 类里面 子类 其它任何地方外边都可以访问 protected 类里面 子类 都可以访问,其它任何地方不能访问 private 类里面可以访问,子类和其它任何地方都不可以访问
class Parent {
public name: string;
protected age: number;
private car: number;
constructor(name: string, age: number, car: number) {
//构造函数
this.name = name;
this.age = age;
this.car = car;
}
getName(): string {
return this.name;
}
setName(name: string): void {
this.name = name;
}
}
class Child extends Parent {
constructor(name: string, age: number, car: number) {
super(name, age, car);
}
desc() {
console.log(`${this.name} ${this.age} ${this.car}`); //car访问不到 会报错
}
}
let child = new Child("hello", 10, 1000);
console.log(child.name);
console.log(child.age); //age访问不到 会报错
console.log(child.car); //car访问不到 会报错
静态属性 静态方法
类的静态属性和方法是直接定义在类本身上面的 所以也只能通过直接调用类的方法和属性来访问
class Parent {
static mainName = "Parent";
static getmainName() {
console.log(this); //注意静态方法里面的this指向的是类本身 而不是类的实例对象 所以静态方法里面只能访问类的静态属性和方法
return this.mainName;
}
public name: string;
constructor(name: string) {
//构造函数
this.name = name;
}
}
console.log(Parent.mainName);
console.log(Parent.getmainName());
抽象类和抽象方法
抽象类,无法被实例化,只能被继承并且无法创建抽象类的实例
子类可以对抽象类进行不同的实现
抽象方法只能出现在抽象类中并且抽象方法不能在抽象类中被具体实现,只能在抽象类的子类中实现(必须要实现)
使用场景:
我们一般用抽象类和抽象方法抽离出事物的共性 以后所有继承的子类必须按照规范去实现自己的具体逻辑 这样可以增加代码的可维护性和复用性
使用 abstract 关键字来定义抽象类和抽象方法
abstract class Animal {
name!: string;
abstract speak(): void;
}
class Cat extends Animal {
speak() {
console.log("喵喵喵");
}
}
let animal = new Animal(); //直接报错 无法创建抽象类的实例
let cat = new Cat();
cat.speak();