一.TS 中定义类
class Pointer {
x!: number; // 实例上的属性必须先声明
y!: number;
constructor(x: number, y?: number, ...args: number[]) {
this.x = x;
this.y = y as number;
}
}
let p = new Pointer(100, 200);
实例上的属性需要先声明在使用,构造函数中的参数可以使用可选参数和剩余参数
二.类中的修饰符
public修饰符(谁都可以访问到)
class Animal {
public name!: string; // 不写public默认也是公开的
public age!: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
class Cat extends Animal {
constructor(name: string, age: number) {
super(name, age);
console.log(this.name, this.age); // 子类访问
}
}
let p = new Cat("Tom", 18);
console.log(p.name, p.age); // 外层访问
class Animal {
constructor(public name: string, public age: number) {
this.name = name;
this.age = age;
}
}
我们可以通过参数属性来简化父类中的代码
protected修饰符 (自己和子类可以访问到)
class Animal {
constructor(protected name: string, protected age: number) {
this.name = name;
this.age = age;
}
}
class Cat extends Animal {
constructor(name: string, age: number) {
super(name, age);
console.log(this.name, this.age);
}
}
let p = new Cat("Tom", 18);
console.log(p.name, p.age); // 无法访问
private修饰符 (除了自己都访问不到)
class Animal {
constructor(private name: string, private age: number) {
this.name = name;
this.age = age;
}
}
class Cat extends Animal {
constructor(name: string, age: number) {
super(name, age);
console.log(this.name, this.age); // 无法访问
}
}
let p = new Cat("Tom", 18);
console.log(p.name, p.age); // 无法访问
readonly修饰符 (仅读修饰符)
class Animal {
constructor(public readonly name: string, public age: number) {
this.name = name;
this.age = age;
}
changeName(name: string) {
this.name = name; // 仅读属性只能在constructor中被赋值
}
}
class Cat extends Animal {
constructor(name: string, age: number) {
super(name, age);
}
}
let p = new Cat("Tom", 18);
p.changeName("Jerry");
三.静态属性和方法
class Animal {
static type = "哺乳动物"; // 静态属性
static getName() {
// 静态方法
return "动物类";
}
private _name: string = "Tom";
get name() {
// 属性访问器
return this._name;
}
set name(name: string) {
this._name = name;
}
}
let animal = new Animal();
console.log(animal.name);
静态属性和静态方法是可以被子类所继承的
四.Super 属性
class Animal {
say(message: string) {
console.log(message);
}
static getType() {
return "动物";
}
}
class Cat extends Animal {
say() {
// 原型方法中的super指代的是父类的原型
super.say("猫猫叫");
}
static getType() {
// 静态方法中的super指代的是父类
return super.getType();
}
}
let cat = new Cat();
console.log(Cat.getType());
五.类的装饰器
1.装饰类
function addSay(target: any) {
target.prototype.say = function () {
console.log("say");
};
}
@addSay
class Person {
say!: Function;
}
let person = new Person();
person.say();
装饰类可以给类扩展功能,需要开启
experimentalDecorators:true
2.装饰类中属性
function toUpperCase(target: any, key: string) {
let value = target[key];
Object.defineProperty(target, key, {
get() {
return value.toUpperCase();
},
set(newValue) {
value = newValue;
},
});
}
function double(target: any, key: string) {
let value = target[key];
Object.defineProperty(target, key, {
get() {
return value * 2;
},
set(newValue) {
value = newValue;
},
});
}
class Person {
@toUpperCase
name: string = "James";
@double
static age: number = 18;
getName() {
return this.name;
}
}
let person = new Person();
console.log(person.getName(), Person.age);
装饰属性可以对属性的内容进行改写,装饰的是实例属性则 target 指向类的原型、装饰的是静态属性则 target 执行类本身~
3.装饰类中方法
function noEnum(target: any, key: string, descriptor: PropertyDescriptor) {
console.log(descriptor);
descriptor.enumerable = false;
}
class Person {
@toUpperCase
name: string = "James";
@double
static age: number = 18;
@noEnum
getName() {
return this.name;
}
}
let person = new Person();
console.log(person); // getName 不可枚举
4.装饰参数
function addPrefix(target: any, key: string, paramIndex: number) {
console.log(target, key, paramIndex); // Person.prototype getName 0
}
class Person {
@toUpperCase
name: string = "James";
@double
static age: number = 18;
prefix!: string;
@noEnum
getName(@addPrefix prefix: string) {
return this.name;
}
}
六.抽象类
抽象类无法被实例化,只能被继承,抽象方法不能在抽象类中实现,只能在抽象类的具体子类中实现,而且必须实现。
abstract class Animal {
name!: string;
abstract speak(): void;
}
class Cat extends Animal {
speak() {
console.log("猫猫叫");
}
}
class Dog extends Animal {
speak(): string {
console.log("汪汪叫");
return "wangwang";
}
}
定义类型时
void表示函数的返回值为空(不关心返回值类型,所有在定义函数时也不关心函数返回值类型)