TS(type,属性修饰符,抽象类,interface)一次性全部总结

目录

1.type

1.基本用法

2.联合类型

3.交叉类型

2.属性修饰符

[1.public 属性修饰符](#1.public 属性修饰符)

属性的简写形式

[2.proteced 属性修饰符](#2.proteced 属性修饰符)

[3.private 属性修饰符](#3.private 属性修饰符)

[4.readonly 属性修饰符](#4.readonly 属性修饰符)

3.抽象类

4.interface

1.定义类结构

2.定义对象结构

3.定义函数结构

4.接口之间的继承

5.接口自动合并

[5. interface和type的区别](#5. interface和type的区别)

[6. interface与抽象类的区别](#6. interface与抽象类的区别)


1.type

type 可以为任意类型创建别名,让代码更简洁,可读性更强,同时能更方便的进行类型复用和扩展。

1.基本用法

TypeScript 复制代码
type num = number;

let price: num
price = 100

2.联合类型

TypeScript 复制代码
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.交叉类型

TypeScript 复制代码
//⾯积
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 属性修饰符

TypeScript 复制代码
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)
TypeScript 复制代码
class Student extends Person {
  constructor(name: string, age: number) {
    super(name, age)
  }

  study() {
    // 【⼦类中】可以访问⽗类中public修饰的:name属性、age属性
    console.log(`${this.age}岁的${this.name}正在努⼒学习`)
  }
}
属性的简写形式
TypeScript 复制代码
class Person {
  constructor(
    public name: string,
    public age: number
  ) {}
}

2.proteced 属性修饰符

TypeScript 复制代码
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
TypeScript 复制代码
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 属性修饰符

TypeScript 复制代码
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 属性修饰符

TypeScript 复制代码
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方法是一个抽象方法,必须由具体的子类来实现。

TypeScript 复制代码
abstract class Package {
  constructor(public weight: number) {}
  // 抽象⽅法:⽤来计算运费,不同类型包裹有不同的计算⽅式
  abstract calculate(): number
  // 通⽤⽅法:打印包裹详情
  printPackage() {
    console.log(`包裹重量为: ${this.weight}kg,运费为: ${this.calculate()}元`)
  }
}
TypeScript 复制代码
// 标准包裹
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()
TypeScript 复制代码
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只能定义格式,不能包含任何实现!

TypeScript 复制代码
// 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.定义对象结构

TypeScript 复制代码
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.定义函数结构

TypeScript 复制代码
interface CountInterface {
  (a: number, b: number): number
}
const count: CountInterface = (x, y) => {
  return x + y
}

4.接口之间的继承

TypeScript 复制代码
interface PersonInterface {
  name: string // 姓名
  age: number // 年龄
}

interface StudentInterface extends PersonInterface {
  grade: string // 年级
}

const stu: StudentInterface = {
  name: '张三',
  age: 25,
  grade: '⾼三'
}

5.接口自动合并

TypeScript 复制代码
// 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的区别

  • 相同点:interfacetype都可以定义对象结构,在定义对象结构时两者可以互换。
  • 不同点:
    • interface:更专注于定义对象和类的结构,支持继承,合并。
    • type:可以定义类型别名,联合类型,交叉类型,但不支持继承和自动合并。

6. interface与抽象类的区别

  • 相同点:都能定义一个类的格式(定义类应遵循的契约)
  • 不同点:
    • 接口:只能描述结构,不能有任何代码实现,一个类可以实现多个接口
    • 抽象类:既可以包含抽象方法,也可以包含具体方法,一个类只能继承一个抽象类
相关推荐
sinat_384241092 分钟前
在有网络连接的机器上打包 electron 及其依赖项,在没有网络连接的机器上安装这些离线包
javascript·arcgis·electron
baiduopenmap14 分钟前
百度世界2024精选公开课:基于地图智能体的导航出行AI应用创新实践
前端·人工智能·百度地图
loooseFish22 分钟前
小程序webview我爱死你了 小程序webview和H5通讯
前端
小牛itbull26 分钟前
ReactPress vs VuePress vs WordPress
开发语言·javascript·reactpress
请叫我欧皇i34 分钟前
html本地离线引入vant和vue2(详细步骤)
开发语言·前端·javascript
533_37 分钟前
[vue] 深拷贝 lodash cloneDeep
前端·javascript·vue.js
guokanglun43 分钟前
空间数据存储格式GeoJSON
前端
GIS瞧葩菜1 小时前
局部修改3dtiles子模型的位置。
开发语言·javascript·ecmascript
zhang-zan1 小时前
nodejs操作selenium-webdriver
前端·javascript·selenium
ZBY520311 小时前
【Vue】 npm install amap-js-api-loader指南
javascript·vue.js·npm