一、class 类相关知识
1.class基本定义
js
class Person {
name: string; //类成员
age: number;//类成员
//构造函数,将name,和age赋值给类成员name和age
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
speak() { //类方法
console.log(`我叫${this.name},今年${this.age}岁`);
}
}
const per1 = new Person("张三", 18);
console.log(per1);
per1.speak();
输出显示

2.类的继承(extends)
js
class Person {
name: string;
age: number;
//构造函数,将name,和age赋值给类成员name和age
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
speak() {
console.log(`我叫${this.name},今年${this.age}岁`);
}
}
class Student extends Person {
grade: string;
//构造函数要写上父类构造函数变量
constructor(name: string, age: number, grade: string) {
//继承父类的成员必须调用supper
super(name, age);
this.grade = grade;
}
study() {
console.log("努力学习");
}
}
const stu1 = new Student("李四", 30, "初一");
console.log(stu1);
stu1.speak();
stu1.study();
输出显示

3.方法重写(override)
js
class Person {
name: string;
age: number;
//构造函数,将name,和age赋值给类成员name和age
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
speak() {
console.log(`我叫${this.name},今年${this.age}岁`);
}
}
class Student extends Person {
grade: string;
//构造函数要写上父类构造函数变量
constructor(name: string, age: number, grade: string) {
//继承父类的成员必须调用supper
super(name, age);
this.grade = grade;
}
study() {
console.log("努力学习");
}
override speak() {
console.log(`我叫${this.name},今年${this.age}岁,今年上${this.grade}`);
}
}
const stu1 = new Student("李四", 30, "初一");
console.log(stu1);
stu1.speak();
输出显示

注意
:override虽然不写也不会报错,但容易让人误导是重写父类的方法,还是自己新写的方法,拼写错误不会有提示,加上override一定是调用父类方法,拼写错误会有提示

4.类的简写
将属性写在构造器里,并用修饰符修饰(必写,public也不能省略)

二、属性修饰符

属性和方法默认为public,public可省略
1.public (公开的:类内部、子类、类外部)
js
//简写后
class Person {
constructor(public name: string, public age: number) {}
speak() {
//类的内部调用public属性
console.log(`我叫${this.name},今年${this.age}岁`);
}
}
class Student extends Person {
study() {
//子类访问父类public属性
console.log(`${this.name}正在努力学习中`);
}
}
const p1 = new Person("张三", 19);
console.log("类的外部访问public属性:", p1.name, p1.age);
//类的外部访问方法
p1.speak();
const s1 = new Student("李四", 10);
s1.study();
输出显示

2.protected(受保护的:类内部、子类)
js
class Person {
constructor(protected name: string, protected age: number) {}
protected getDetails() {
//类的内部调用protected属性
return `我叫${this.name},今年${this.age}岁`;
}
introduce() {
console.log(this.getDetails());
}
}
class Student extends Person {
study() {
//子类访问父类protected属性
console.log(this.getDetails());
console.log(`${this.name}正在努力学习中`);
}
}
const p1 = new Person("张三", 19);
//类的外部不能访问protected修饰的属性
// p1.name; //报错:属性"name"受保护,只能在类"Person"及其子类中访问
// p1.age; //报错:属性"age"受保护,只能在类"Person"及其子类中访问
// p1.getDetails(); //报错:属性"getDetails"受保护,只能在类"Person"及其子类中访问
p1.introduce();
const s1 = new Student("李四", 30);
s1.study();
输出显示

3.private(私有的:类内部)
js
class Person {
constructor(
public name: string,
public age: number,
private IDCard: string
) {}
private getPrivateInfo() {
//类内部访问private属性
return `身份证号码为:${this.IDCard}`;
}
getDetails() {
return `我叫${this.name},今年${this.age}岁`;
}
getFullInfo() {
console.log(this.getDetails() + this.getPrivateInfo());
}
}
const p1 = new Person("张三", 19, "500101199523451223");
//类的外部不能访问protected修饰的属性
p1.name;
p1.age;
p1.getFullInfo();
// p1.IDCard;//报错:属性"IDCard"为私有属性,只能在类"Person"中访问
// p1.getPrivateInfo();//报错:属性"getPrivateInfo"为私有属性,只能在类"Person"中访问。
输出显示

4.readonly(只读的:属性无法修改)
js
class Person {
constructor(public readonly name: string, public age: number) {}
}
const p1 = new Person("张三", 19);
//类的外部不能访问protected修饰的属性
console.log(p1);
p1.age = 28;
console.log(p1);
// p1.name = "李四"; //报错:无法为"name"赋值,因为它是只读属性
输出显示

三、抽象类
1.概述
(1) 定义:抽象类是一种无法被实例化
的类,专门用来定义类的结构和行为
,类中可以写抽象方法
,也可以写具体实现
。 抽象类主要用来为其派生类提供一个基础结构
,要求其派生类必须实现其中的抽象方法
。
(2) 简记:抽象类不能被实例化,其意义是可以被继承,抽象类中可以有普通方法和抽象方法,继承类必须实现抽象方法。
(3)案例说明
需求:我们定义一个抽象类Package,表示所有包裹的基本结构,任何包裹都有重量属性weight,包裹都需 要计算运费。但不同类型的包裹(如:标准速度、特快专递)都有不同的运费计算方式,因此用于计算运 费的calcu1ate方法是一个抽象方法,必须由具体的子类来实现。
js
//定义一个包裹抽象类
abstract class Package {
//构造方法
constructor(public weight: number) {}
//抽象方法
abstract calculate(): number;
//具体方法
printPackage() {
console.log(`包裹重量为${this.weight}kg,运费为${this.calculate()}元`);
}
}
//普通包裹类,继承抽象类必须包含抽象类的结构
class NormalPackage extends Package {
constructor(weight: number, public unitPrice: number) {
super(weight);
}
calculate(): number {
return this.weight * this.unitPrice;
}
info() {
console.log(`我是普通包裹`);
}
}
const normalPackage = new NormalPackage(10, 2);
normalPackage.info();
normalPackage.printPackage();
//特快包裹类
class FastPackage extends Package {
constructor(weight: number, public unitPrice: number) {
super(weight);
}
calculate(): number {
if (this.weight > 10) {
return (this.weight - 10) * 2 + 10 * this.unitPrice;
} else {
return this.weight * this.unitPrice;
}
}
info() {
console.log(`我是特快包裹`);
}
}
const fastPackage = new FastPackage(18, 5);
fastPackage.info();
fastPackage.printPackage();
输出显示

(4) 总结(何时使用抽象类)
- 定义通用接口:为一组相关的类定义通用的行为(属性或方法)时。
- 提供基础实现:在抽象类中提供某些方法或为其提供基础实现,这样派生类就可以继承这些实现。
- 确保关键实现:强制派生类实现关键行为(抽象方法)
- 共享代码和逻辑:当多个类需要共享部分代码时,抽象类可以避免代码重复。