Typescript Class 类
简单示例
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
访问类型
public
公共的,默认的。允许类的内外部调用prevate
私有的。允许类的内部调用protected
保护的。允许类的内部和派生类(继承的子类)的内部调用
语法
// 方法一
class Person {
public name: string = "姓名";
}
// 方法二
class Person {
constructor(public name: string) {}
}
继承
extends
允许使用继承来扩展现有的类
语法
class <派生类> extends <基类> {
constructor() {
super(); // 执行基类的构造函数
}
}
示例
class Person {
name: string = "无名氏";
age: number = 0;
type: string = "未知类型";
constructor({name, age, type}:{ name: string; age:number; type: string}) {
this.name = name;
this.age = age;
this.type = type
}
}
class Teacher extends Person {
subjects: string[] = [];
constructor({name, age, subjects}:{ name: string; age:number; subjects: string[]}) {
super({name, age, type: "教师"});
this.subjects = subjects;
}
}
const teacher = new Teacher({
name: "马化腾",
age: 50,
subjects: ["抄袭学","坑钱学"]
});
console.log(teacher);
/*
Teacher {
name: '马化腾',
age: 50,
type: '教师',
subjects: [ '抄袭学', '坑钱学' ]
}
*/
类从基类中继承了属性和方法。 这里, Teacher
是一个 派生类,它派生自 Person
基类,通过 extends
关键字。 派生类通常被称作 子类,基类通常被称作 超类。
派生类包含了一个构造函数,它 必须调用 super()
,它会执行基类的构造函数。 而且,在构造函数里访问 this
的属性之前,我们 一定要调用 super()
。 这个是TypeScript强制执行的一条重要规则。
存取器 get、set
TypeScript支持通过getters/setters来截取对对象成员的访问。 它能帮助你有效的控制对对象成员的访问。
class Person {
constructor (private _name: string) {
this._name = _name;
}
get name(): string {
// 可加工后输出
console.log("输出:", this._name);
return this._name;
}
set name(_name: string) {
// 可加工后写入
console.log("写入:", _name);
this._name = _name;
}
}
const p = new Person('马化腾');
p.name;
// 输出:马化腾
p.name = "马化疼";
// 写入:马化疼
静态属性
static
静态属性存在于类本身上面而不是类的实例上
class Demo {
str1: string = "Demo";
static arr: number[] = [];
constructor (v:number) {
// this.arr.push(v)
// 错误 属性“arr”在类型“Demo”上不存在。你的意思是改为访问静态成员“Demo.arr”吗?
Demo.arr.push(v)
}
add(v: number) {
// this.arr.push(v)
// 错误 属性“arr”在类型“Demo”上不存在。你的意思是改为访问静态成员“Demo.arr”吗?
Demo.arr.push(v)
}
// 静态属性的 this 指向 类本身 (Demo 本身)
static add(v:number) {
// this.str1
// 类型“typeof Demo”上不存在属性“str1”。
this.arr.push(v);
}
}
const demo1 = new Demo(1);
// demo1.arr
// 属性“arr”在类型“Demo”上不存在。你的意思是改为访问静态成员“Demo.arr”吗?
Demo.arr.push(1)
readonly 修饰符
readonly
关键字将属性设置为只读的。 只读属性必须在声明时或构造函数里被初始化。
抽象类
抽象类做为其它派生类的基类使用,不能被实例化。不同于接口,抽象类可以包含成员的实现细节。 abstract
关键字是用于定义抽象类和在抽象类内部定义抽象方法。
abstract class Department {
constructor(public name: string) {
}
printName(): void {
console.log('Department name: ' + this.name);
}
abstract printMeeting(): void; // 必须在派生类中实现
}
class AccountingDepartment extends Department {
constructor() {
super('Accounting and Auditing'); // 在派生类的构造函数中必须调用 super()
}
printMeeting(): void {
console.log('The Accounting Department meets each Monday at 10am.');
}
generateReports(): void {
console.log('Generating accounting reports...');
}
}
let department: Department; // 允许创建一个对抽象类型的引用
department = new Department(); // 错误: 不能创建一个抽象类的实例
department = new AccountingDepartment(); // 允许对一个抽象子类进行实例化和赋值
department.printName();
department.printMeeting();
department.generateReports(); // 错误: 方法在声明的抽象类中不存在
其他
唯一类写法
class Demo {
private static demo: Demo;
private constructor(public name: string) {}
static getDemo() {
if (!this.demo) {
this.demo = new Demo('唯一类');
}
return this.demo;
}
}
const demo1 = Demo.getDemo();
const demo2 = Demo.getDemo();
console.log(demo1 === demo2); // true