目录
1.type
1.基本用法
2.联合类型
3.交叉类型
2.属性修饰符
1.public 属性修饰符
属性的简写形式
2.proteced 属性修饰符
3.private 属性修饰符
4.readonly 属性修饰符
3.抽象类
4.interface
1.定义类结构
2.定义对象结构
3.定义函数结构
4.接口之间的继承
5.接口自动合并
5. interface和type的区别
6. interface与抽象类的区别
1.type
type 可以为任意类型创建别名,让代码更简洁,可读性更强,同时能更方便的进行类型复用和扩展。
1.基本用法
type num = number;
let price: num
price = 100
2.联合类型
type Status = number | string
type Gender = '男' | '⼥'
function printStatus(status: Status) {
console.log(status)
}
function logGender(str: Gender) {
console.log(str)
}
printStatus(404)
printStatus('200')
printStatus('501')
logGender('男')
logGender('⼥')
3.交叉类型
//⾯积
type Area = {
height: number //⾼
width: number //宽
}
//地址
type Address = {
num: number //楼号
cell: number //单元号
room: string //房间号
}
// 定义类型House,且House是Area和Address组成的交叉类型
type House = Area & Address
const house: House = {
height: 180,
width: 75,
num: 6,
cell: 3,
room: '702'
}
2.属性修饰符
1.public 属性修饰符
class Person {
// name写了public修饰符,age没写修饰符,最终都是public修饰符
public name: string
age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
speak() {
// 类的【内部】可以访问public修饰的name和age
console.log(`我叫:${this.name},今年${this.age}岁`)
}
}
const p1 = new Person('张三', 18)
// 类的【外部】可以访问public修饰的属性
console.log(p1.name)
class Student extends Person {
constructor(name: string, age: number) {
super(name, age)
}
study() {
// 【⼦类中】可以访问⽗类中public修饰的:name属性、age属性
console.log(`${this.age}岁的${this.name}正在努⼒学习`)
}
}
属性的简写形式
class Person {
constructor(
public name: string,
public age: number
) {}
}
2.proteced 属性修饰符
class Person {
// name和age是受保护属性,不能在类外部访问,但可以在【类】与【⼦类】中访问
constructor(
protected name: string,
protected age: number
) {}
// getDetails是受保护⽅法,不能在类外部访问,但可以在【类】与【⼦类】中访问
protected getDetails(): string {
// 类中能访问受保护的name和age属性
return `我叫:${this.name},年龄是:${this.age}`
}
// introduce是公开⽅法,类、⼦类、类外部都能使⽤
introduce() {
// 类中能访问受保护的getDetails⽅法
console.log(this.getDetails())
}
}
const p1 = new Person('杨超越', 18)
// 可以在类外部访问introduce
p1.introduce()
// 以下代码均报错
// p1.getDetails()
// p1.name
// p1.age
class Student extends Person {
constructor(name: string, age: number) {
super(name, age)
}
study() {
// ⼦类中可以访问introduce
this.introduce()
// ⼦类中可以访问name
console.log(`${this.name}正在努⼒学习`)
}
}
const s1 = new Student('tom', 17)
s1.introduce()
3.private 属性修饰符
class Person {
constructor(
public name: string,
public age: number,
// IDCard属性为私有的(private)属性,只能在【类内部】使⽤
private IDCard: string
) {}
private getPrivateInfo() {
// 类内部可以访问私有的(private)属性 —— IDCard
return `身份证号码为:${this.IDCard}`
}
getInfo() {
// 类内部可以访问受保护的(protected)属性 —— name和age
return `我叫: ${this.name}, 今年刚满${this.age}岁`
}
getFullInfo() {
// 类内部可以访问公开的getInfo⽅法,也可以访问私有的getPrivateInfo⽅法
return this.getInfo() + ',' + this.getPrivateInfo()
}
}
const p1 = new Person('张三', 18, '110114198702034432')
console.log(p1.getFullInfo())
console.log(p1.getInfo())
// 以下代码均报错
// p1.name
// p1.age
// p1.IDCard
// p1.getPrivateInfo()
4.readonly 属性修饰符
class Car {
constructor(
public readonly vin: string, //⻋辆识别码,为只读属性
public readonly year: number, //出⼚年份,为只读属性
public color: string,
public sound: string
) {}
// 打印⻋辆信息
displayInfo() {
console.log(`
识别码:${this.vin},
出⼚年份:${this.year},
颜⾊:${this.color},
⾳响:${this.sound}
`)
}
}
const car = new Car('1HGCM82633A123456', 2018, '⿊⾊', 'Bose⾳响')
car.displayInfo()
// 以下代码均错误:不能修改 readonly 属性
// car.vin = '897WYE87HA8SGDD8SDGHF';
// car.year = 2020;
3.抽象类
简记:抽象类不能被实例化,其意义是可以被继承,抽象类里可以有普通方法,也可以有抽象方法。
通过以下场景,理解抽象类:
我们定义一个抽象类
Package
,表示所有包裹的基本结构,任何包裹都有重量属性weight
,包裹需要计算费用。但不同类型的包裹(如:标准速度,特快专递)都有不同的计算方式,因此用于计算费用的calculate
方法是一个抽象方法,必须由具体的子类来实现。
abstract class Package {
constructor(public weight: number) {}
// 抽象⽅法:⽤来计算运费,不同类型包裹有不同的计算⽅式
abstract calculate(): number
// 通⽤⽅法:打印包裹详情
printPackage() {
console.log(`包裹重量为: ${this.weight}kg,运费为: ${this.calculate()}元`)
}
}
// 标准包裹
class StandardPackage extends Package {
constructor(
weight: number,
public unitPrice: number // 每公⽄的固定费率
) {
super(weight)
}
// 实现抽象⽅法:计算运费
calculate(): number {
return this.weight * this.unitPrice
}
}
// 创建标准包裹实例
const s1 = new StandardPackage(10, 5)
s1.printPackage()
class ExpressPackage extends Package {
constructor(
weight: number,
private unitPrice: number, // 每公⽄的固定费率(快速包裹更⾼)
private additional: number // 超出10kg以后的附加费
) {
super(weight)
}
// 实现抽象⽅法:计算运费
calculate(): number {
if (this.weight > 10) {
// 超出10kg的部分,每公⽄多收additional对应的价格
return 10 * this.unitPrice + (this.weight - 10) * this.additional
} else {
return this.weight * this.unitPrice
}
}
}
// 创建特快包裹实例
const e1 = new ExpressPackage(13, 8, 2)
e1.printPackage()
像是这样的形式我自己有自己的理解形式:
好比如我们走路,起点都是一样的,终点也是一样的,唯独我们的过程是不一样的,有的骑车,有的走路等等,但是这多种方式我们就可以写成继承的方式,那么我们总共花费的时间就可以写在这个抽象类里面。
4.interface
1.定义类结构
interface
是一种定义结构的方式,主要作用是为:类,对象,函数等规定一种契约,这样可以确保代码的一致性和类型安全,但要注意interface
只能定义格式,不能包含任何实现!
// PersonInterface接⼝,⽤与限制Person类的格式
interface PersonInterface {
name: string
age: number
speak(n: number): void
}
// 定义⼀个类 Person,实现 PersonInterface 接⼝
class Person implements PersonInterface {
constructor(
public name: string,
public age: number
) {}
// 实现接⼝中的 speak ⽅法
speak(n: number): void {
for (let i = 0; i < n; i++) {
// 打印出包含名字和年龄的问候语句
console.log(`你好,我叫${this.name},我的年龄是${this.age}`)
}
}
}
// 创建⼀个 Person 类的实例 p1,传⼊名字 'tom' 和年龄 18
const p1 = new Person('tom', 18)
p1.speak(3)
2.定义对象结构
interface UserInterface {
name: string
readonly gender: string // 只读属性
age?: number // 可选属性
run: (n: number) => void
}
const user: UserInterface = {
name: '张三',
gender: '男',
age: 18,
run(n) {
console.log(`奔跑了${n}⽶`)
}
}
3.定义函数结构
interface CountInterface {
(a: number, b: number): number
}
const count: CountInterface = (x, y) => {
return x + y
}
4.接口之间的继承
interface PersonInterface {
name: string // 姓名
age: number // 年龄
}
interface StudentInterface extends PersonInterface {
grade: string // 年级
}
const stu: StudentInterface = {
name: '张三',
age: 25,
grade: '⾼三'
}
5.接口自动合并
// PersonInterface接⼝
interface PersonInterface {
// 属性声明
name: string
age: number
}
// 给PersonInterface接⼝添加新属性
interface PersonInterface {
// ⽅法声明
speak(): void
}
// Person类实现PersonInterface
class Person implements PersonInterface {
name: string
age: number
// 构造器
constructor(name: string, age: number) {
this.name = name
this.age = age
}
// ⽅法
speak() {
console.log('你好!我是⽼师:', this.name)
}
}
5. interface和type的区别
- 相同点:
interface
和type
都可以定义对象结构,在定义对象结构时两者可以互换。 - 不同点:
interface
:更专注于定义对象和类的结构,支持继承,合并。type
:可以定义类型别名,联合类型,交叉类型,但不支持继承和自动合并。
6. interface与抽象类的区别
- 相同点:都能定义一个类的格式(定义类应遵循的契约)
- 不同点:
- 接口:只能描述结构,不能有任何代码实现,一个类可以实现多个接口
- 抽象类:既可以包含抽象方法,也可以包含具体方法,一个类只能继承一个抽象类