TypeScript 类
类是面向对象编程(OOP)的核心概念,它是一种模板或蓝图,用于创建具有相同属性和方法的对象。TypeScript 完全支持面向对象编程,提供了类、继承、访问修饰符等特性。
类封装了数据(属性)和行为(方法),使得代码更加模块化、可复用和易维护。通过类,我们可以创建多个具有相同结构的对象,这些对象称为类的实例。
类的定义
TypeScript 使用 class 关键字定义类。一个类可以包含以下成员:
- 字段(Field):类中声明的变量,表示对象的属性
- 构造函数(Constructor):类实例化时调用的特殊方法,用于初始化对象
- 方法(Method):类中定义的函数,表示对象的行为
语法格式
class class_name {
// 字段声明
field1: type;
field2: type;
// 构造函数
constructor(parameters) {
// 初始化代码
}
// 方法
methodName(): return_type {
// 方法实现
}
}
实例:创建简单的类
实例
class Person {
}
编译后的 JavaScript:
实例
function Person() {
}
return Person;
}());
类的字段和构造函数
类的字段是存储对象数据的地方,构造函数在对象创建时自动调用,用于初始化字段。
实例
class Car {
// 字段:描述汽车的属性
engine: string;
// 构造函数:在创建对象时初始化 engine
constructor(engine: string) {
this.engine = engine;
}
// 方法:显示发动机信息
disp(): void {
console.log("发动机型号: " + this.engine);
}
}
// 创建类的实例
var car = new Car("V8 发动机");
// 访问字段
console.log("读取发动机: " + car.engine);
// 调用方法
car.disp();
运行结果:
读取发动机: V8 发动机 发动机型号: V8 发动机
说明:
this关键字指向当前类的实例- 构造函数的参数名可以与字段名相同,通过
this.field区分 - 使用
new关键字创建类的实例
注意:TypeScript 的类在编译后会转换为 JavaScript 的构造函数原型模式,接口不会出现在编译结果中。
访问控制修饰符
TypeScript 提供了三种访问修饰符来控制类成员的可访问性:
| 修饰符 | 说明 |
|---|---|
public |
公有成员,可以在任何地方访问(默认) |
private |
私有成员,只能在类内部访问 |
protected |
受保护成员,可以在类内部和子类中访问 |
public(默认)
实例
public name: string; // 公有属性
public age: number; // 公有属性
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
public introduce(): void {
console.log("我是 " + this.name + ",今年 " + this.age + " 岁");
}
}
var person = new Person("Alice", 25);
console.log("姓名: " + person.name); // 可以访问
person.introduce(); // 可以访问
private(私有)
实例
public name: string;
private secret: string; // 私有属性,外部无法直接访问
constructor(name: string, secret: string) {
this.name = name;
this.secret = secret;
}
// 公有方法可以访问私有属性
public revealSecret(): void {
console.log("秘密: " + this.secret);
}
}
var person = new Person("Alice", "我喜欢编程");
console.log("姓名: " + person.name); // 可以访问
// console.log(person.secret); // 错误:'secret' 是私有属性
person.revealSecret(); // 通过公有方法访问私有属性
protected(受保护)
实例
protected name: string; // 受保护属性
constructor(name: string) {
this.name = name;
}
protected sayHello(): void {
console.log("你好,我是 " + this.name);
}
}
class Student extends Person {
private grade: string;
constructor(name: string, grade: string) {
super(name);
this.grade = grade;
}
public introduce(): void {
// 子类可以访问受保护的属性和方法
console.log("我是 " + this.name + ",年级: " + this.grade);
this.sayHello();
}
}
var student = new Student("Bob", "高三");
student.introduce(); // 可以访问
// console.log(student.name); // 错误:'name' 是受保护属性
运行结果:
我是 Bob,年级: 高三 你好,我是 Bob
类的继承
继承允许创建一个类(子类)从另一个类(父类)获取属性和方法。子类可以复用父类的代码,还可以扩展或重写父类的行为。
基本语法
class child_class extends parent_class {
// 子类新增的属性和方法
}
单继承
实例
class Shape {
area: number;
constructor(a: number) {
this.area = a;
}
}
// 子类:圆,继承自 Shape
class Circle extends Shape {
disp(): void {
console.log("圆的面积: " + this.area);
}
}
var circle = new Circle(223);
circle.disp();
运行结果:
圆的面积: 223
多重继承
TypeScript 不支持多继承(一个类继承多个类),但支持多层继承(A 继承 B,B 继承 C):
实例
class Root {
str: string;
}
// 子类:继承 Root
class Child extends Root {
}
// 叶子类:继承 Child(多重继承)
class Leaf extends Child {
}
var leaf = new Leaf();
leaf.str = "hello";
console.log("str 值: " + leaf.str);
运行结果:
str 值: hello
方法重写(Override)
子类可以重写(Override)父类的方法,即在子类中定义与父类同名的方法,实现自己的行为。
使用 super 关键字可以调用父类的方法。
实例
class PrinterClass {
doPrint(): void {
console.log("父类的 doPrint() 方法");
}
}
// 子类:重写父类方法
class StringPrinter extends PrinterClass {
doPrint(): void {
// 调用父类的方法
super.doPrint();
// 子类自己的逻辑
console.log("子类的 doPrint() 方法");
}
}
var obj = new StringPrinter();
obj.doPrint();
运行结果:
父类的 doPrint() 方法 子类的 doPrint() 方法
静态成员
使用 static 关键字定义的成员属于类本身,而不是类的实例。可以直接通过类名访问,不需要创建实例。
实例
// 静态属性
static num: number;
// 静态方法
static disp(): void {
console.log("num 值为 " + StaticMem.num);
}
}
// 直接通过类名访问静态成员
StaticMem.num = 12;
StaticMem.disp();
运行结果:
num 值为 12
应用场景:静态成员常用于定义类的常量、工具方法或单例模式。
instanceof 运算符
instanceof 用于判断对象是否是某个类的实例。
实例
}
var obj = new Person();
var isPerson = obj instanceof Person;
console.log("obj 是 Person 类的实例吗? " + isPerson);
运行结果:
obj 是 Person 类的实例吗? true
类实现接口
类可以使用 implements 关键字实现接口,确保类符合接口定义的契约。
实例
interface ILoan {
interest: number; // 利率
}
// 类实现接口
class AgriLoan implements ILoan {
interest: number;
rebate: number; // 回扣
constructor(interest: number, rebate: number) {
this.interest = interest;
this.rebate = rebate;
}
}
var loan = new AgriLoan(10, 1);
console.log("利率: " + loan.interest + "%,回扣: " + loan.rebate);
运行结果:
利率: 10%,回扣: 1
抽象类
抽象类不能被实例化,只能作为基类供子类继承。抽象类可以包含抽象方法(没有实现的占位方法),子类必须实现这些方法。
实例
abstract class Animal {
abstract makeSound(): void; // 抽象方法,子类必须实现
move(): void {
console.log("动物在移动");
}
}
// 具体类:继承抽象类
class Dog extends Animal {
makeSound(): void {
console.log("汪汪汪!");
}
}
var dog = new Dog();
dog.move();
dog.makeSound();
运行结果:
动物在移动 汪汪汪!
综合实例
综合运用类的各种特性:
实例
interface I Printable {
print(): void;
}
// 抽象类
abstract class Item {
protected name: string;
protected price: number;
constructor(name: string, price: number) {
this.name = name;
this.price = price;
}
abstract getDetails(): string;
}
// 具体类
class Product extends Item implements I Printable {
private category: string;
constructor(name: string, price: number, category: string) {
super(name, price);
this.category = category;
}
// 实现抽象方法
getDetails(): string {
return `产品: ${this.name}, 价格: ¥${this.price}, 类别: ${this.category}`;
}
// 实现接口方法
print(): void {
console.log(this.getDetails());
}
// 静态方法
static create(name: string, price: number): Product {
return new Product(name, price, "默认类别");
}
}
// 使用
var product = Product.create("笔记本电脑", 5999);
product.print();
// 折扣方法
class DiscountedProduct extends Product {
private discount: number;
constructor(name: string, price: number, category: string, discount: number) {
super(name, price, category);
this.discount = discount;
}
getDetails(): string {
var discountedPrice = this.price * (1 - this.discount / 100);
return `产品: ${this.name}, 原价: ¥${this.price}, 折扣: ${this.discount}%, 现价: ¥${discountedPrice.toFixed(2)}`;
}
}
var discountedProduct = new DiscountedProduct("手机", 2999, "电子产品", 20);
discountedProduct.print();
运行结果:
产品: 笔记本电脑, 价格: ¥5999, 类别: 默认类别 产品: 手机, 原价: ¥2999, 折扣: 20%, 现价: ¥2399.20
总结
TypeScript 的类提供了完整的面向对象编程支持:
- 类的定义:使用 class 关键字,包含字段、构造函数和方法
- 访问修饰符:public、private、protected 控制成员访问权限
- 继承:使用 extends 实现类继承,支持多层继承
- 方法重写:子类可以重写父类方法,使用 super 调用父类
- 静态成员:使用 static 关键字,属于类本身而非实例
- 接口实现:使用 implements 关键字实现接口
- 抽象类:使用 abstract 关键字,不能实例化,作为基类
类是 TypeScript 面向对象编程的基础,合理使用类可以使代码更加结构化和可维护。
