6.interface
interface(接口) 是 TS 设计出来用于定义对象类型的,可以对对象的形状进行描述。
1. 基本概念
定义 interface 一般首字母大写,代码如下:
注:interface 只是在 TS 中用来做静态编码检查。 并不会被转换为js
// 定义 interface 一般首字母大写,代码如下:
interface 类型Types {
name: string
age: number
sex: string
num: any
}
const p1: Types = {
name: 'lin',
age: 18,
sex: 'man',
num: 123
}
// 注意:interface 不是 JS 中的关键字,所以 TS 编译成 JS 之后,这些 interface 是不会被转换过去的,都会被删除掉,
// interface 只是在 TS 中用来做静态检查。
2. 可选属性 ?
在属性上加个 ? 这个属性就是可选的,比如下面的 age 属性 防止报错
interface Types {
name: string
sex?: string
}
const p1: Types = {
name: 'lin',
}
3. 只读属性 readonly
如果希望某个属性不被改变
interface Types {
readonly name: string
}
const p1: Types = {
name: 'lin',
}
p1.name = 'lin1'
4. 描述函数类型
interface FunType {
(x:number,y:number):number
}
const add:FunType = (num1, num2) => {
return num1 + num2
}
console.log(add(1,2));
5. 自定义属性
interface LikeArray {
[propName: number]: string
}
const arr: LikeArray = ['hello', 'lin']
arr[0] // 这样的arr 是一个伪数组 所以可以使用下标来访问值
伪数组是没有数组的方法的
6. duck typing 奇葩定义
// duck typing
定义了函数的类型 又定义了一个fnName的属性定义
interface FunctionWithProps {
(x: number): number //函数类型的定义
fnName: string //参数类型定义
}
const fn: FunctionWithProps = (x) => {
return x
}
fn.fnName = 'hello world'
7.类
封装 继承 多态 三大特点
// 类 的封装 继承 多态
// 定义一个 Person 类,有属性 name 和 方法 speak
class Person {
name: string
constructor(name: string) {
this.name = name
}
speak() {
console.log(`${this.name} is speaking`)
}
}
const p1 = new Person('lin') // 新建实例
p1.name // 访问属性和方法
p1.speak()
7.1 继承
//继承 Person 类
class Student extends Person {
fun_name() {
console.log(`${this.name} is speaking`)
}
}
const p2 = new Student('man')
p2.fun_name()
// 继承之后,Student 类上的实例可以访问 Person 类上的属性和方法。
7.2 super关键字
上例中 Student 类没有定义自己的属性,可以不写 super ,
但是如果 Student 类有自己的属性,就要用到 super 关键字来把父类的属性继承过来。
// super关键字
// 上例中 Student 类没有定义自己的属性,可以不写 super ,
// 但是如果 Student 类有自己的属性,就要用到 super 关键字来把父类的属性继承过来。
class Students extends Person {
grade: number
constructor(name: string,grade:number) {
super(name) // 调用父类的构造函数
this.grade = grade
}
}
const p3 = new Students('man',100)
console.log(p3.grade);
7.3 public 公有的
公有的,一个类里默认所有的方法和属性都是public public 可写可不写,不写默认也是 public
class strPerson {
public name: string
public constructor(name: string) {
this.name = name
}
public speak() {
console.log(`${this.name} is speaking`)
}
}
const p4 = new strPerson('test')
p4.speak() // lin is speaking
7.4 private 私有的
// private,私有的,只属于这个类自己,它的实例和继承它的子类都访问不到。
// 将 Person 类的 name 属性改为 private。
class Persons {
private name: string
public constructor(name: string) {
this.name = name
}
public speak() {
console.log(`${this.name} is speaking`)
}
}
const p5 = new Persons('test_p5')
p5.name //属性“name”为私有属性,只能在类“Persons”中访问
7.5 protected 受保护的
// protected 受保护的,继承它的子类可以访问,实例不能访问。
// 将 Person 类的 name 属性改为 protected。
class Person {
protected name: string
public constructor(name: string) {
this.name = name
}
public speak() {
console.log(`${this.name} is speaking`)
}
}
const p = new Person('test_p')
p.speak() //属性“name”受保护,只能在类“Person”及其子类中访问
class Studeng extends Person {
study() {
console.log(`${this.name} needs study`)
}
}
const p1 = new Studeng('test_p1')
p1.study()
7.6 static
// static
// static 是静态属性,可以理解为是类上的一些常量,实例不能访问。
// 比如一个 Circle 类,圆周率是 3.14,可以直接定义一个静态属性。
class Circle {
static pi = 3.14
public radius: number
public constructor(radius: number) {
this.radius = radius
}
public calcLength() {
return Circle.pi * this.radius * 2 // 计算周长,直接访问 Circle.pi
}
}
const c = new Circle(5)
c.pi // 属性“pi”在类型“Circle”上不存在。你的意思是改为访问静态成员“Circle.pi”吗?
console.log(c.calcLength()) // 31.4