目录
TS 中定义类 类中实例属性、方法 + 修饰符 public protected private readonly 实例方法 类中原型属性、方法 + 访问器 原型属性 + 访问器 原型方法 类中静态属性、方法 子类重写父类方法 类中 Super 属性 修饰符 + constructor(){} 抽象类 abstract 抽象类定义实例方法及原型方法类的组成部分: 构造函数、属性(实例属性、原型属性、静态属性)、方法(实例方法、原型方法、静态方法、访问器)
TS 中定义类
实例属性/方法:所有实例上的属性和方法都需要 先声明后再使用
class Circle { x: number; y: number; constructor(x: number, y: number = 0, ...args: number[]) { // 默认值、剩余运算符 this.x = x; this.y = y; } } let circle = new Circle(100);
类中实例属性、方法 + 修饰符
上述代码当构造函数参数比较多时,声明就会显得很多,结构不友好,此时需要使用 类的修饰符 来解决,表示可访问的范围或权限
类的修饰符分类: public (公开的:自己,子类,外界)、 protected (受保护的:自己、子类)、 private (私有的:自己)、 readonly (只读的)
public
class Animal { /* public name!: string; // 不写public默认也是公开的 public age!: number; constructor(name: string, age: number) { this.name = name; this.age = age; } */ // 可以简写为:直接在参数前添加对应的修饰符,就会默认添加到实例中,相当于已经声明 constructor(public name: string, public 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); // 外层访问
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); // 异常:属性“name”受保护,只能在类“Animal”及其子类中访问
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); // 异常:属性“name”为私有属性,只能在类“Animal”中访问。 } } let p = new Cat("Tom", 18); console.log(p.name, p.age); // 异常:属性“name”为私有属性,只能在类“Animal”中访问。
readonly
仅读属性只能在 constructor 中被赋值,因为是相当于初始化
class Animal { constructor(public readonly name: string, public age: number) { this.name = name; // 仅读属性只能在constructor中被赋值,因为是相当于初始化 this.age = age; } changeName(name: string) { this.name = name; // 异常:无法分配到 "name" ,因为它是只读属性。 } } class Cat extends Animal { constructor(name: string, age: number) { super(name, age); } } let p = new Cat("Tom", 18); p.changeName("Jerry");
实例方法
class Animal { public eat: () => void; // 实例方法 constructor() { this.eat = () => { console.log("eat"); }; } } let an = new Animal(); an.eat();
类中原型属性、方法 + 访问器
原型属性 + 访问器
class Animal { private _name: string = "Tom"; // 原型属性 get name() { // 需要通过类的访问器,访问 原型上的属性 return this._name; } set name(newValue) { this._name = newValue; } } let an = new Animal(); console.log(an.name);
原型方法
class Animal { say(message: string) { console.log(message); } } let an = new Animal(); an.say("hello");
类中静态属性、方法
静态属性、方法都是通过 类名直接调用 ,并且静态属性和静态方法是 可以被子类所继承 的
class Animal { static type = "哺乳动物"; // 静态属性 // 静态方法 static getName() { return "动物类"; } } class Cat extends Animal {} console.log(Animal.type); console.log(Animal.getName()); console.log(Cat.type); console.log(Cat.getName());
子类重写父类方法
要求必须和父类的方法类型一致,也就是说方法的入参与返回值的类型,需要 兼容 父类方法的类型
class Animal { static getType(ms: string) { console.log("父"); } say(ms: string): void { console.log("父 say"); } } class Mouse extends Animal { static getType() { console.log("子"); } say() { console.log("子 say"); return 123; } } let mouse = new Mouse(); mouse.say(); Mouse.getType();
类中 Super 属性
原型方法中的 super 指代父类的原型 静态方法中的 super 指代父类 构造函数中的 super 指代父类class Animal2 { static getType() { console.log("父"); } public eat: () => void; constructor() { this.eat = () => { console.log("eat"); }; } say(): void { console.log("父 say"); } } class Mouse extends Animal2 { static getType() { console.log("子"); super.getType(); // super 指代父类 } constructor() { super(); // super 指代父类 } say() { console.log("子 say"); super.say(); // super 指代父类的原型 } } let mouse = new Mouse(); mouse.say(); // 依次打印:子 say、 父 say、 mouse.eat(); // 打印:子 say、 父 say、 Mouse.getType(); // 依次打印:子、 父
修饰符 + constructor(){}
构造函数中增加了 private 和 protected,表示父类不能被 new,此时使用场景并不是很多,通常多见于 单例模式
单例模式
class Singleton { static instance = new Singleton(); private constructor() {} // 默认不写 是public static getInstance() { return this.instance; } } // 单例模式 let instance1 = Singleton.getInstance(); let instance2 = Singleton.getInstance(); console.log(instance1 === instance2); // true
抽象类 abstract
抽象类的特点:
由 abstract 修饰的类叫做抽象类,也可以修饰 抽象方法 抽象方法不能在抽象类中实现,只能在抽象类的具体子类中实现,而且必须实现。 只有抽象类中可以有抽象方法, 抽象类中可以有普通方法,普通方法不需要被子类重写 抽象类不能被实例化,也就是不能 new,只能被继承 定义类型时 void 表示函数的返回值为空(不关心返回值类型,所有在定义函数时也不关心函数返回值类型)abstract class Animal { // 1 abstract speak(): void; // 3, drink() { // 4 console.log("drink"); } } class Cat extends Animal { speak() { // 2 console.log("猫叫"); } } class Dog extends Animal { speak(): string { // 6 console.log("汪叫"); return "wangwang"; } } new Animal(); // 5. 报异常:无法创建抽象类的实例
抽象类定义实例方法及原型方法
实例方法
abstract class Person { abstract eat: () => void; // 定义实例方法 } class Teacher extends Person { eat: () => void; // 属性“eat” 初始化,且需要在构造函数中明确赋值。 constructor() { super(); // 访问派生类的构造函数中的 this前,必须调用"super"。 this.eat = function () { console.log("eat"); }; } }
原型方法
abstract class Person { abstract eat(): void; // 定义原型方法 } class Teacher extends Person { eat(): void { // 非抽象类"Teacher"需要实现父类"Person”"的抽象成员"eat"。 console.log("eat"); } }
查看更多关于TypeScript 学习笔记 — 类的基本用法(五)的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://www.haodehen.cn/did223180