把现实中的物体抽象到程序里面,就是以对象(Object)的形式存在的。
对象数据被称为属性。
对象的功能被称为方法。
类 class
人类,狗类…,一系列相似物体的集合,相同的类具有相同的属性和方法
定义

class cat {name: string;age: number;static maxAge: number = 10; // 静态属性,就是这个类统一的属性run() {console.log("running")}eat() {console.log("eatting")}}
实例 new xxx( )
就是类的一个实例,可以想象成猫类其中有一只叫做Tom,毛是灰色的,Tom是cat类的一个实例。
let Tom = new cat() // 创建实例
属性、方法
公共属性(public 或 省略):普通的属性都是公共属性,任意访问和修改
只读属性(readonly):只能读取,不能修改值
静态属性(static):这个类统一的属性,可以直接访问这个类的静态属性,而不是通过实例
私有属性(private):实例无法直接获取或修改的属性,只能通过这个类的某些方法来获取或修改。
好处是主动权在这个类,我不想让你获取不想让你改,你就没法搞。
或者你获取、修改时可以进行判断,符合我想要的规则,才让你搞。
子类继承后也无法直接操作私属性。
保护属性(protected):受保护的属性,只能在自己类或者子类中访问和修改,无法通过实例访问修改
class cat {// 定义的是实例属性,需要通过创建实例并赋予初始值才能访问name: string;readonly leg: number = 4;// 只读属性,只能读取,不能修改值// 静态属性,就是这个类统一的属性,可以直接访问这个类的静态属性static maxAge: number = 10;// 私有属性,只有这个类有,实例无法去修改,只能通过类的方法去访问private _life:number = 9// 构造函数,见下constructor(n:string){this.name = n}// 定义实例的方法,需要通过创建实例就可以直接调用执行函数run() {console.log("running")}// 静态方法,就是这个类统一的属性,可以直接调用这个类的静态方法static eat() {console.log("eatting")}// 一般通过方法获取私有属性的值showLife(){return `猫有${this._life}条命`}// 或者通过 get方法 获取私有属性的值get life(){return this._life}// 一般通过方法修改私有属性的值die(n:number){this._life -= n; // 只能通过自己的方法,修改私有属性console.log(`还剩下${this._life}条命`);}// 或者通过 set方法 修改私有属性的值set life(n:number){if (n>0) {this._life = n}}}const Tom = new cat("Tom")console.log(Tom.name)console.log(cat.maxAge) // 可以直接访问这个类的静态属性console.log(Tom.showLife()) // 无法直接访问私有属性,必须通过内部的方法console.log(Tom.life) // 无法直接访问私有属性,除非get方法定义后才能访问console.log(Tom.die(2)) // 无法直接修改私有属性,必须通过内部的方法console.log(Tom.life = 8) // 无法直接修改私有属性,除非set方法定义后才能修改Tom.run()cat.eat() // 可以调用访问这个类的静态方法
构造函数(构造方法) constructor
创建实例时,告诉程序怎么给实例赋予初始值
class cat {name: string ;age: number ;static maxAge: number = 10;// 定义构造器,用于帮助创建实例时,赋予初始值// 每创建一个实例,都会调用一次构造函数constructor(n:string,a:number){console.log(this); // this 指的是当前新创建的实例this.name = n; // 传参数进来赋初始值this.age = a;}run() {console.log(this.name + " is running") // this 指的是当前新创建的实例}static eat() {console.log("eatting")}}const Tom = new cat("Tom",4)console.log(Tom);Tom.run(); // Tom is running
简写
!可能为空
ts会判断你将要赋值的有没有可能为空,严格的验证可能会报错,如果你确定不会为空,可以加一个!号在后面,告诉ts我确定这个不会为空
继承 extends
可以继承某个类的所有属性和方法,方便减少代码量
/*** 动物类* 定义一个动物类*/class animal {name: string ;age: number ;constructor(n:string,a:number){console.log(this); // this 指的是当前新创建的实例this.name = n; // 传参数进来赋初始值this.age = a;}run() {console.log(this.name + " is running")}say() {console.log("动物在叫")}}/*** 猫类* 定义一个猫类,继承动物类,猫也算动物,可以有名字、年龄等动物的属性,和跑步、叫喊等动物的方法*/class cat extends animal { // 继承// 也可以额外定义猫类自己的属性leg:number = 4;color:string;// 子类的构造函数要注意,需要调用父类的构造函数,传父类需要的参数constructor(n:string,a:number, l:number,c:string){super(n,a); // 这里调用父类构造函数,把子类创建实例时的参数传入this.leg = l;this.color = c;}eat() {console.log("eatting")}run() {super.run() // super 表示父类,这里调用父类的方法}say(){ // 重写父类的方法console.log("喵")}}const Tom = new cat("Tom",4,4,"black")Tom.say(); // 喵
抽象类 abstract

接口 interface
可以当做声明一个类型使用,对类进行限制,而且可以重复定义(自定义类型不可以重复定义),重复的结果是叠加。
属性不允许有实际值,方法都是抽象方法(没有实体),只考虑结构
接口就是定义一个规范,就像水管的接口,必须满足一定的规范,才能连接起来。
实现接口 implements,就是怎么满足规范。

抽象类和接口的区别
1、抽象类,可以有普通属性普通方法,也可以有抽象方法
接口,全都是没有属性,抽象方法
2、抽象类用继承 extends
接口用实现 implements
泛型

用法
1、前期不确定类型,使用时再确定,此时搞个变量,用变量表示类型

2、限定函数的参数必须具有某些属性
类分模块
每个类放在单独文件里,然后用es6的 export 暴露这个类,其他页面需要时 import 导入这个类
====================
HTML接口
HTML元素

感叹号!是告诉ts,我们确定这个不为空,否则会提示有可能为空
