主要记录ts中的类、接口与泛型
1.类
无论是在哪种语言中,类都是面向对象编程(OOP)
的一个主要实现方式。能够实现代码更加灵活,更具有结构化。类作用都是提供一个模板,通过类可以创建多个具有相同结构的对象。
// 类的定义,与对象的声明
class Student {
id: string
name: string
age: number
constructor(id:string, name:string, age:number) { // 构造器
this.id = id
this.name = name
this.age = age
}
speak() {
console.log('I am a student, my name is' + this.name);
}
}
let stu1 = new Student('0001','小王', 18)
let stu2 = new Student('0002','小刘', 19)
let stu3 = new Student('0003','小李', 20)
- 类的继承
// 类的继承
class SeniorStudent extends Student { // 继承父类
grade:string
constructor(id:string, name:string, age:number,grade:string) {
super(id, name, age) // 通过super把父类需要的参数传入
this.grade = grade
}
override speak(): void { // 重写speak方法
console.log('I am a senior student, I am '+ this.name + ', i am in grade '+this.grade);
}
}
let sen1 = new SeniorStudent('0007', '小L', 18, '高三')
sen1.speak() // I am a senior student, I am 小L, i am in grade 高三
-
类属性的修饰符
-
public
:使用public
修饰的成员属性或者成员方法既能在自身类中和子类调用也能在类外部调用; -
private
:使用private
修饰的成员属性或者成员方法只能在自身类中调用; -
protected
:使用protect
修饰的成员属性或者成员方法只能在自身类中和子类调用,不能在类外部调用; -
readonly
:使用readonly
修饰的成员属性无法修改。
-
-
抽象类和抽象方法
抽象类用
abstract
来修饰。抽象类的作用是为派生类提供一个基础结构,抽象类可以被继承不能被实例化。抽象类中的方法可以是抽象方法(用abstract
修饰),也可以是普通方法。其中的抽象方法一定要被派生类实现。
// 抽象类
abstract class Cup{
shape: string;
price: number;
private readonly resource: string
constructor(shape:string, price:number, resource:string) {
this.shape = shape
this.price = price
this.resource = resource
}
getInfo() {
console.log('Infos: shape is ' + this.shape+ 'resource is ' + this.resource + 'price is ' + this.price );
}
abstract changePrice(val:number): void //抽象函数不能够实现具体功能,只能声明参数你返回值
}
class glassCup extends Cup {
constructor(shape: string, price:number, resource:string, private volumn:number) {
super(shape, price, resource)
}
changePrice(val: number): void {
this.price = this.price - val
console.log('the price change to ' + this.price);
}
}
思考: 在实践这段代码的时候,我有个小想法。之前函数定义的方法有下面这种格式的,表示:
声明一个函数,函数名为countSum, 并且指定形参和形参类型,同时通过=>指定返回值类型
。这种形式的函数声明也是一个声明方式,没有实际实现,那么我是否可以用这种方式来定义抽象类中的抽象方法呢?
- 我不知道
abstract
关键字加在哪
- 在代码中尝试写了不加abstract关键字的格式,代码报错
let countSum :(x:number, y:number)=>number
上面这种格式只适用于函数声明,不适用于类方法
2.接口
接口是用于规范类、函数、对象的结构。接口只能定义格式,不能像类一样被实现。通过关键词implement
调用接口。
// 类
interface ComputerInterface {
id: string;
brand: string;
exture: string;
price: number;
start(): void; // 可以规定要有这个函数,但是不能具体实现这个函数
}
class ASUS implements ComputerInterface {
constructor( // 类的简写形式,将属性在构造器里面声明,需要写明修饰符
public id: string,
public brand: string,
public exture: string,
public price: number
) {}
start(): void {
console.log(this.brand + 'is starting....');
}
}
let asus1 = new ASUS('0001', '华硕', '轻薄本', 5000)
接口规范对象,注意写法
//接口规范对象
interface ObjectInterface {
name: string
age: number
gender?:string // 可选
}
let obj1: ObjectInterface = { // 注意写法
name: 'no_name',
age: 18
}
定义函数规范,写法跟对象类似,也在写这个过程中感受到了ts的一些特点,比如:必须先声明res且定义其为空字符才能进行后面的相加和赋值;
// 接口定义函数的规范
interface FunInterface {
(a:string, b:number):string
}
let printString: FunInterface = (a: string, n: number) => {
let res = ''
for (let i = 0; i < n; i++) res = res + a
return res
// return a.repeat(n)
}
接口也可以继承。接口还能够合并,在某个地方定义接口a后,继续又定义了接口a并写了新的属性,两个接口会合并成一个