类与面向对象编程
🎯 引言
学完这篇文章,你能清楚分辨 ES6 和 TS 中类与面向对象编程的异同,能够用 TS 编写规范的面向对象代码。你会了解类定义、访问修饰符、继承与实现、抽象类与接口等基础知识,并知道哪些是 ES6 支持的,哪些是 TS 独有的特性。
✨ class 定义与构造函数
在 ES6 之前,JavaScript 主要基于原型链实现面向对象。ES6 引入了 class 关键字,让我们像传统面向对象语言那样定义类。TS 对 ES6 的类进行了增强和类型约束。
// ES6 的类定义及构造函数
class Person {
constructor(name) {
this.name = name;
}
sayHello() {
console.log('Hello, ' + this.name);
}
}
const p = new Person('小红');
p.sayHello();
以上代码是 ES6 支持的。TS 也是这样写类的,但可以加上类型声明,让代码更严谨:
// TS 类定义,带类型
class Person {
name: string;
constructor(name: string) {
this.name = name;
}
sayHello(): void {
console.log('Hello, ' + this.name);
}
}
const p = new Person('小红');
p.sayHello();
🔐 public、private、protected 访问修饰符
这是 TS 在类上的独家特性。ES6 本身不支持访问修饰符,所有属性和方法默认都是公开的。
public表示公有,可以从类外访问(TS 默认就是public)private表示私有,只能在类内部访问protected表示受保护,只能在类内部和子类访问
class Person {
public name: string; // 公有属性
private age: number; // 私有属性
protected gender: string; // 受保护属性
constructor(name: string, age: number, gender: string) {
this.name = name;
this.age = age;
this.gender = gender;
}
public sayHello(): void {
console.log(`Hi, I'm ${this.name}`);
}
private getAge(): number {
return this.age;
}
}
🧬 继承与实现
继承是 ES6 也支持的基本特性。用 extends 关键字实现子类继承父类。
// ES6 继承示例
class Animal {
constructor(name) {
this.name = name;
}
move() {
console.log(this.name + ' 在移动');
}
}
class Dog extends Animal {
bark() {
console.log('汪汪');
}
}
const dog = new Dog('小白');
dog.move();
dog.bark();
TS 继承写法类似,但可以加类型声明:
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
move(): void {
console.log(this.name + ' 在移动');
}
}
class Dog extends Animal {
bark(): void {
console.log('汪汪');
}
}
const dog = new Dog('小白');
dog.move();
dog.bark();
实现(Implement)接口
实现接口是 TS 独有的概念,ES6 没有接口。接口用于定义类必须实现的属性和方法,属于静态类型检查。
interface Flyable {
fly(): void;
}
class Bird implements Flyable {
fly(): void {
console.log('我会飞');
}
}
如果类没有实现接口中的所有方法,TS 会报错。
🏗 抽象类与接口
抽象类
抽象类是 TS 独有的概念,ES6 不支持。
抽象类不能直接实例化,通常用于作为基类,定义子类必须实现的方法。
abstract class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
abstract makeSound(): void; // 抽象方法,必须由子类实现
move(): void {
console.log(this.name + ' 在移动');
}
}
class Cat extends Animal {
makeSound(): void {
console.log('喵喵');
}
}
const cat = new Cat('小花');
cat.makeSound();
接口
接口定义了类的外部形状,不包含具体实现。一个类可以实现多个接口。
interface Swimmer {
swim(): void;
}
interface Flyer {
fly(): void;
}
class Duck implements Swimmer, Flyer {
swim(): void {
console.log('鸭子游泳');
}
fly(): void {
console.log('鸭子飞翔');
}
}
🧾 小节总结
- ES6 原生支持类定义、构造函数和继承(
class、constructor、extends),但不支持访问修饰符、接口和抽象类。 - TS 在 ES6 类基础上添加了访问修饰符(
public、private、protected),接口(interface),抽象类(abstract class)等强类型和面向对象的特性。 - 接口和抽象类是 TS 独有的,可以用来规范代码结构和抽象行为,增加代码的可维护性。
❓ 知识问答(Q&A)
Q:ES6 中的类和 TS 类最大的区别是什么?
A:ES6 仅支持类的基本语法和继承关系,TS 在此基础上增加了访问修饰符、类型声明、接口和抽象类等面向对象特性。
Q:访问修饰符在编译后的 JS 代码中是否有效?
A:访问修饰符只在 TS 编译阶段生效,编译成 JS 后不存在访问限制,但开发时提示错误,保证代码规范。
Q:接口和抽象类有什么不同?
A:接口只定义规范,没有具体实现,类可以实现多个接口;抽象类可以包含具体实现和抽象方法,不能实例化,只能被继承。
🧪 小练习
练习 1
写一个 Vehicle 抽象类,包含一个抽象方法 move(),和一个普通方法 stop()。然后写一个 Car 类继承 Vehicle 并实现 move() 方法。
abstract class Vehicle {
abstract move(): void;
stop(): void {
console.log('停止');
}
}
// 在这里写 Car 类,继承 Vehicle 并实现 move()
练习 2
定义一个接口 Playable,包含方法 play(), 写一个类 Music 实现这个接口,并在 play() 方法中输出播放音乐的提示。
interface Playable {
play(): void;
}
// 写 Music 类,实现 Playable 接口
🎉 恭喜你已经掌握 TS 类定义、访问修饰符、继承与实现、抽象类与接口技能啦! 面向对象的思想能帮助你写出更结构化、可维护的代码,TS 的类型系统让这个过程更可靠。继续练习,你会更得心应手!
