TypeScript是一种基于JavaScript的编程语言,它支持静态类型检查和面向对象的特性。TypeScript中的interface和class是两种重要的概念,它们可以用来定义对象的结构和行为。在本文中,我将介绍TypeScript中interface和class的含义、用法和区别。
interface的含义和用法
• interface是一种用来描述对象的形状(shape)或契约(contract)的语法,它可以指定对象必须具有哪些属性和方法,以及它们的类型。interface只存在于编译时,不会生成任何运行时代码,只用于类型检查。
• interface的使用方法很简单,只需要用interface关键字来声明一个接口,然后用冒号(:)来分隔属性名和属性类型,用分号(;)来结束每个属性声明。例如:
// 定义一个Person接口
interface Person {
name: string; // 姓名属性,类型为string
age: number; // 年龄属性,类型为number
sayHello(): void; // sayHello方法,返回类型为void
}
• 我们可以用冒号(:)来指定一个变量、参数或返回值的类型为某个接口,然后赋值或传递一个符合该接口要求的对象。例如:
// 定义一个变量p,类型为Person接口
let p: Person = {
name: 'Alice', // 姓名为Alice
age: 20, // 年龄为20
sayHello() { // sayHello方法
console.log('Hello, I am ' + this.name);
}
};
// 定义一个函数greet,参数类型为Person接口,返回类型为string
function greet(person: Person): string {
person.sayHello(); // 调用person的sayHello方法
return 'Nice to meet you, ' + person.name; // 返回一句问候语
}
// 调用greet函数,传入p作为参数
console.log(greet(p)); // 输出:Hello, I am Alice. Nice to meet you, Alice.
• interface还可以定义可选属性(optional property),只需要在属性名后面加上问号(?)即可。这表示该属性可以存在或不存在,但如果存在则必须符合指定的类型。例如:
// 定义一个Animal接口,有一个可选属性color
interface Animal {
name: string; // 名字属性,类型为string
color?: string; // 颜色属性,类型为string,可选
}
// 定义一个变量a1,类型为Animal接口,赋值一个有颜色属性的对象
let a1: Animal = {
name: 'Cat',
color: 'Black'
};
// 定义一个变量a2,类型为Animal接口,赋值一个没有颜色属性的对象
let a2: Animal = {
name: 'Dog'
};
• interface还可以定义只读属性(readonly property),只需要在属性名前面加上readonly关键字即可。这表示该属性只能在对象创建时赋值,不能再修改。例如:
// 定义一个Point接口,有两个只读属性x和y
interface Point {
readonly x: number; // x坐标,类型为number,只读
readonly y: number; // y坐标,类型为number,只读
}
// 定义一个变量p1,类型为Point接口,赋值一个对象
let p1: Point = {
x: 10,
y: 20
};
// 尝试修改p1的x属性
p1.x = 30; // error: Cannot assign to 'x' because it is a read-only property.
• interface还可以继承(extend)其他接口,形成更复杂的接口。继承的方式是在接口名后面加上extends关键字,然后跟上一个或多个要继承的接口名。这表示该接口包含了所有父接口的属性和方法,并且可以添加自己的属性和方法。例如:
// 定义一个Shape接口,有一个只读属性name
interface Shape {
readonly name: string; // 形状名称,类型为string,只读
}
// 定义一个Circle接口,继承Shape接口,添加一个属性radius
interface Circle extends Shape {
radius: number; // 半径,类型为number
}
// 定义一个Rectangle接口,继承Shape接口,添加两个属性width和height
interface Rectangle extends Shape {
width: number; // 宽度,类型为number
height: number; // 高度,类型为number
}
// 定义一个变量c,类型为Circle接口,赋值一个对象
let c: Circle = {
name: 'Circle', // 继承自Shape接口的name属性
radius: 10 // 自己的radius属性
};
// 定义一个变量r,类型为Rectangle接口,赋值一个对象
let r: Rectangle = {
name: 'Rectangle', // 继承自Shape接口的name属性
width: 20, // 自己的width属性
height: 30 // 自己的height属性
};
TypeScript是一种基于JavaScript的编程语言,它支持静态类型检查和面向对象的特性。TypeScript中的class是一种用来创建对象的模板或构造函数,它可以定义对象的属性和方法,并且可以实现封装、继承和多态等面向对象的特性。class既存在于编译时,也存在于运行时,它会生成对应的JavaScript代码。
class的使用方法也很简单,只需要用class关键字来声明一个类,然后用花括号({})来包裹类的内容。类的内容包括构造函数(constructor)、属性(property)和方法(method)。例如:
// 定义一个Person类
class Person {
name: string; // 姓名属性,类型为string
age: number; // 年龄属性,类型为number
// 构造函数,用来初始化属性
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
// sayHello方法,返回类型为void
sayHello(): void {
console.log('Hello, I am ' + this.name);
}
}
我们可以用new关键字来创建一个类的实例(instance),即根据类的模板生成一个具体的对象。我们可以给构造函数传递一些参数来初始化对象的属性。例如:
// 创建一个Person类的实例p,传入姓名和年龄作为参数
let p = new Person('Alice', 20);
// 调用p的sayHello方法
p.sayHello(); // 输出:Hello, I am Alice.
class还可以实现封装(encapsulation),即控制类的内部细节对外部的可见性。TypeScript提供了三种访问修饰符(access modifier)来实现封装:public、private和protected。public表示公开的,可以在任何地方访问;private表示私有的,只能在类内部访问;protected表示受保护的,只能在类内部或子类中访问。例如:
// 定义一个Animal类
class Animal {
public name: string; // 公开的姓名属性,类型为string
private age: number; // 私有的年龄属性,类型为number
// 构造函数,用来初始化属性
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
// 公开的getAge方法,返回类型为number
public getAge(): number {
return this.age;
}
// 私有的setAge方法,参数类型为number,返回类型为void
private setAge(age: number): void {
this.age = age;
}
}
// 创建一个Animal类的实例a,传入姓名和年龄作为参数
let a = new Animal('Cat', 3);
// 访问a的name属性
console.log(a.name); // 输出:Cat
// 访问a的age属性
console.log(a.age); // error: Property 'age' is private and only accessible within class 'Animal'.
class还可以继承(inherit)其他类,形成父子关系。继承的方式是在子类名后面加上extends关键字,然后跟上父类名。这表示子类包含了父类的所有属性和方法,并且可以添加或覆盖自己的属性和方法。例如:
// 定义一个Shape类,有一个只读属性name
class Shape {
readonly name: string; // 形状名称,类型为string,只读
// 构造函数,用来初始化name属性
constructor(name: string) {
this.name = name;
}
}
// 定义一个Circle类,继承Shape类,添加一个属性radius
class Circle extends Shape {
radius: number; // 半径,类型为number
// 构造函数,用来初始化radius属性,并调用父类的构造函数
constructor(radius: number) {
super('Circle'); // 调用父类Shape的构造函数,并传入name参数
this.radius = radius;
}
// 重写父类的方法,返回类型为void
sayHello(): void {
console.log('Hello, I am a ' + this.name + ' with radius ' + this.radius);
}
}
// 创建一个Circle类的实例c,传入半径作为参数
let c = new Circle(10);
// 调用c的sayHello方法
c.sayHello(); // 输出:Hello, I am a Circle with radius 10.
• interface是一种用来描述对象的形状(shape)或契约(contract)的语法,它只指定对象必须具有哪些属性和方法,以及它们的类型。interface只存在于编译时,不会生成任何运行时代码,只用于类型检查。https://jameshenry.blog/typescript-classes-vs-interfaces/https://www.typescriptlang.org/docs/handbook/interfaces.html
• class是一种用来创建对象的模板或构造函数,它不仅定义了对象的属性和方法,还提供了它们的实现。class既存在于编译时,也存在于运行时,它会生成对应的JavaScript代码,并且可以实现封装、继承和多态等面向对象的特性。
• interface可以继承(extend)其他接口,形成更复杂的接口。interface也可以被class实现(implement),表示class必须遵循interface的要求。
• class可以继承(inherit)其他类,形成父子关系。class也可以实现(implement)多个接口,表示class必须遵循所有接口的要求。
• interface可以定义可选属性(optional property)、只读属性(readonly property)、索引签名(index signature)等特殊的类型。class则不能定义这些类型,但可以使用访问修饰符(access modifier)来控制属性和方法的可见性。