当前位置: 首页 > news >正文

TypeScript 学习之Class

基本使用

class Greeter {// 属性greeting: string;// 构造函数constructor(message: string) {// 用this 访问类的属性this.greeting = message;}// 方法greet() {return 'Hello, ' + this.greeting;}
}
// 实例化
let greeter = new Greeter('World');

声明了一个Greeter类,类有三个成员:一个是 greeting属性,一个构造函数和一个greet方法。使用new关键字实例化Greeter对象。实例化时会调用类的构造函数,并返回一个对象。

继承

使用 extends 关键字。
派生类(子类) 包含构造函数就必须调用super()

class Animal {move(distanceInMeters: number = 0) {console.log(`Animal moved ${distanceInMeters}`);}
}class Dog extends Animal {bark() {console.log('Woof! Woof');}
}const dog = new Dog();
dog.bark();
dog.move(10);
dog.bark();

最基本的继承:类从基类中继承了属性和方法。

class Animal {name: string;constructor(theName: string) {this.name = theName;}move(distanceInMeters: number = 0) {console.log(`${this.name} moved ${distanceInMeters}`);}
}class Snake extends Animal {constructor(name: string) {super(name);}// 重写父类move方法move(distanceInMeters = 5) {console.log('Slithering....');super.move(distanceInMeters);}
}class Horse extends Animal {constructor(name: string) {super(name);}// 重写父类move方法move(distanceInMeters = 45) {console.log('Galloping....');super.move(distanceInMeters);}
}let sam = new Snake('Sammy the Python');
let tom: Animal = new Horse('Tommy the Palomino');sam.move();
tom.move(34);

公有、私有与受保护的修饰符

在类中所有成员都默认被公有public修饰符修饰。

  • public 公有
    • 公有(public)成员可能在类的外部访问
class Animal {public name: string;public constructor(theName: string) {this.name = theName;}public move(distanceInMeters: number) {console.log(`${this.name} moved ${distanceInMeters}`);}
}let animal = new Animal('dog');
animal.name = 'Cat';
animal.move(20);
  • private 私有
    • 当成员被标记成private时,属性或方法就不能在类的外部访问
    • 子类不能访问父类的 private 修饰的属性
    • constructor 可以被 private 修饰,但是这样类就不能被实例化,也不能被子类继承
class Animal {private name: string;constructor(theName: string) {this.name = theName;}
}class Dog extends Animal {constructor(theName: string) {super(theName);}move() {console.log(`${this.name}`); // 报错,子类不能访问父类的私有属性}
}
let animal = new Animal('dog');
animal.name = 'cat'; // 报错,name 是私有属性,类外不能访问
  • 如果两个的类型的所有成员的类型都是兼容的,那么这两类型是兼容的。但是这两个类型的其中一个类型包含private成员,那么只有当另一个类型中也存在这样一个 private成员,并且来自同一处声明时,才能认为这两个类型是兼容的 protected成员也使用这个规则
class Animal {private name: string;constructor(theName: string) {this.name = theName;}
}class Rhino extends Animal {constructor() {super('Rhino');}
}class Employee {private name: string;constructor(theName: string) {this.name = theName;}
}let animal = new Animal('Goat');
let rhino = new Rhino();
let employee = new Employee('Bob');animal = rhino;
animal = employee; // 错误:Animal 与 Employee 不兼容
  • protected 保护
    • 子类可以访问父类的 protected 修饰的成员。但是protected修饰的成员不能再类的外部访问
    • constructor可以被protected修饰,但是类不能被实例化,可以被子类继承
class Person {protected name: string;constructor(name: string) {this.name = name;}
}class Employee extends Person {private department: string;constructor(name: string, department: string) {super(name);this.department = department;}public getElevatorPitch() {return `Hello, my name is ${this.name} and I work in ${this.department}`;}
}let howard = new Employee('Howard', 'Sales');
console.log(howard.getElevatorPitch());
console.log(howard.name); // 错误,protected 修饰的属性不能再类的外部访问

readonly 修饰符

  • readonly关键字将属性设置为只读的,只读属性必须在声明时或构造函数里被初始化。
class Octopus {readonly name: string;readonly numberOfLegs: number = 8;constructor(theName: string) {this.name = theName;}
}let dad = new Octopus('Man with the 8 strong legs');
dad.name = 'Man with the 3-piece suit'; // 错误,name是只读的

参数属性

参数属性通过给构造函数参数前面添加一个访问限定符来声明。
会同时声明并初始化一个成员

  • 使用readonly修饰的属性与构造函数的参数结合。
class Octopus {readonly numberOfLegs: number = 8;constructor(readonly name: string) {}
}let dad = new Octopus('Man with the 8 strong legs');
dad.name = 'Man with the 3-piece suit'; // 错误 namename 只读console.log(dad.name);
  • 使用 public修饰的属性与构造函数的参数结合。
class Octopus {readonly numberOfLegs: number = 8;constructor(public name: string) {}
}let dad = new Octopus('man');
console.log(dad.name);
  • 使用 private修饰的属性与构造函数的参数结合。
class Octopus {readonly numberOfLegs: number = 8;constructor(private name: string) {}getName() {return this.name;}
}let dad = new Octopus('man');
console.log(dad.getName());
  • 使用 protected修饰的属性与构造函数的参数结合。
class Octopus {readonly numberOfLegs: number = 8;constructor(protected name: string) {}getName() {return this.name;}
}let dad = new Octopus('man');
console.log(dad.getName());

存储器

typescript 支持通过 getters/setters 来截取对对象成员的访问。
只有get没有set的会自动被推断为readonly

let passcode = 'secret passcode';class Employee {private _fullName: string;get fullName(): string {return this._fullName;}set fullName(newName: string) {if (passcode && passcode == 'secret passcode') {this._fullName = newName;} else {console.log('Error: Unauthorized update of employee!');}}
}let employee = new Employee();
employee.fullName = 'Bob Smith';if (employee.fullName) {alert(employee.fullName);
}

静态属性

关键字: static
静态属性是存在于类本身,不存在与类的实例。
同一个类的实例对象共享类上的静态属性的状态。
通过类名.方式访问静态属性

class Grid {static origin = {x: 0, y: 0};constructor(public scale: number) {}calculateDistanceFromOrigin(point: {x: number; y: number}) {let xDist = point.x - Grid.origin.x;let yDist = point.y - Grid.origin.y;return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale;}
}let grid1 = new Grid(1.0);
let grid2 = new Grid(5.0);console.log(grid1.calculateDistanceFromOrigin({x: 10, y: 10}));
console.log(grid2.calculateDistanceFromOrigin({x: 10, y: 10}));

抽象类

关键字: abstract
抽象类不能直接被实例化,只能通过派生类(子类)继承,实例化派生类(子类)。
抽象类类似于接口,但是抽象类可以包含成员的实现细节。
抽象类的抽象方法不包含具体实现并且必须在派生类(子类)中实现。
抽象方法必须在方法前声明abstract关键字并且可以包含访问修饰符

abstract class Deparment {constructor(public name: string) {}printName(): void {console.log('Department name: ' + this.name);}abstract printMeeting(): void; // 必须在派生类中实现
}class AccountingDepartment extends Deparment {constructor() {super('Accounting and Auditing'); // 在派生类的构造函数必须调用}printMeeting(): void {console.log('The Accounting Department meets each Monday at 10am.');}generateReports(): void {console.log('Generating accounting reports...');}
}let department: Deparment; // 允许创建一个抽象类型的引用
// department = new Deparment(); // 错误 不能创建一个抽象类的实例
department = new AccountingDepartment(); // 允许创建一个抽象子类进行实例化和赋值
department.printName();
department.printMeeting();
// department.generateReports(); // 错误:方法在声明的抽象类中不存在

构造函数

  • 类的实例化会调用类的构造函数
class Greeter {static standardGreeting = 'Hello, there';greeting: string;greet() {if (this.greeting) {return 'Hello, ' + this.greeting;} else {return Greeter.standardGreeting;}}
}let greeter1: Greeter;
greeter1 = new Greeter();
console.log(greeter1.greet());let greeterMaker: typeof Greeter = Greeter;
greeterMaker.standardGreeting = 'Hey there!';let greeter2: Greeter = new greeterMaker();
console.log(greeter2.greet());

特别注意:创建一个greeterMaker的变量,这个变量保存了这个类或者说保存了类构造函数。然后用typeof greeter,意思是取Greeter类的类型,而不是实例的类型,也就是构造函数的类型。这个类型包含了类的所有静态成员和构造函数。

类当作接口使用

类定义会创建类的实例类型和一个构造函数

class Point {x: number;y: number;
}
interface Point3d extends Point {z: number;
}let point3d: Point3d = {x: 1, y: 2, z: 3};
http://www.lryc.cn/news/9690.html

相关文章:

  • doris - 数仓 拉链表 按天全量打宽表性能优化
  • 服务器虚拟化及优势
  • 华为ensp模拟校园网/企业网实例(同城灾备及异地备份中心保证网络安全)
  • git命令篇(持续更新中)
  • 用记事本实现“HelloWorld”输出
  • Python基础1
  • 4.2 双点双向路由重发布
  • AcWing《蓝桥杯集训·每日一题》—— 3768 字符串删减
  • 第五天笔记
  • 如何使用ArcGIS进行地理配准
  • 【java基础知识】
  • Java提供了哪些IO方式? NIO如何实现多路复用?
  • 人的大脑遇事的思考解决过程
  • GNU zlib 压缩与解压文件详细介绍
  • 离线环境轻量级自动化部署
  • In-context Learning
  • 【新2023】华为OD机试 - 最优调度策略(Python)
  • Python列表系列之统计计算
  • 【蓝桥杯集训·每日一题】AcWing 1460. 我在哪?
  • 一个不可忽视的重要能力
  • 2023.2.6-2.12 AI行业周刊(第136期):住院
  • 听说2年以上的自动化测试都有16k+,4年10k的你还要等待奇迹吗?
  • git 命令实战
  • 基于机器学习LSTM的古代汉语切分标注算法及语料库研究 完整代码+数据+论文
  • 魔百和M401A刷入Armbian系统EMMC开启wifi
  • 超实用的小红书内容营销策略分享!纯干货
  • 高压放大器在介电泳效应的细胞分选研究中的应用
  • Redis三 高级篇-3. 最佳实践
  • 基于 VPX 总线的工件台运动控制系统研究与开发-以光刻运动台为例(一)
  • 回溯算法理论基础