前言
小伙伴们大家好。前面我们已经掌握了TypeScript中变量的声明和使用。而我们知道TypeScript与JavaScript一样都是一种面向对象的编程语言,而面向对象的程序设计必然少不了信息的封装,而类又是信息封装的基础。因此类是面向对象程序设计中一个必不可少的类型。今天就跟大家一起学习一下TypeScript中的类。
类
类的概念: 类是对现实生活中一类具有相同特征的事物的抽象。那么在程序设计里,类是由程序员自己定义的一种引用数据类型。类的内部会定义一些属性和方法,用于对类本身的一个描述和操作。
在传统的JavaScript中,通过定义构造函数和原型继承的方式来实现组件的重用,在es6以后新增了class(类)的概念,从而我们可以基于真正的类来实现面向对象的编程。在TypeScript中同样也支持基于类的面向对象编程。
类的定义:
- 定义一个类需要借助 class关键字,如:class 类名{}
- 一个类中一般由构造函数、属性和方法组成(称为类的成员),用于描述类的特征和行为
- 类的实例通过 new关键字来创建
- 类可以被继承,通过 extends关键字实现类的继承
- 类的成员可分为:
- 实例成员:不加关键字默认为实例成员,通过类的实例进行访问和设置
- 静态成员:通过 static关键字定义静态成员,静态成员需要直接通过类名来访问和设置
- 类的访问修饰符:TypeScript中可以通过访问修饰符来控制对类成员的访问,TypeScript中类的访问修饰符分为三种:
- public(默认):公有,用public修饰的成员可以在任意地方被访问,默认类的成员都是public的
- protected:受保护的,用protected修饰的类的成员只能在当前类内部或者其子类中使用
- private:私有的,用private修饰的类成员为私有成员,只能在类的内部使用
- 在类的内部可以通过 this关键字来访问类的实例成员,类内部的this一般指向类的实例
- 在类的内部可以用readonly关键字定义只读属性,但只读属性必须在声明时或在构造函数中初始化
下面我们以定义一个Person类为例,对类进行进一步的了解。
首先我们分析一下:一个人一般都有姓名、年龄、体重、性别,身高、身份证号等等这些属性,这些我们就可以定义为类的属性。同时人还可以说话、吃饭、运动、等等行为,那么这些就可以定义为类的方法,另外我们再看像身份证这类信息,应该是私密信息不能随便让别人使用,所以身份证属性我们就可以设置为private
//定义一个类需要借助 class关键字
//一个类中一般由构造函数、属性和方法组成(称为类的成员),用于描述类的特征和行为
class Person{
//定义属性
name:string;
age:number;
sex:number;
high:number;
weight:number;
//访问修饰符,默认为public
private readonly idCard:string; //私有只读属性
protected surName:string; //可被继承
//构造函数 定义形参,可以通过构造函数来给属性赋值
constructor(name:string,age:number,sex:number){
//在类的内部可以通过 this关键字来访问类的实例成员,类内部的this一般指向类的实例
this.name = name;
this.age = age;
this.sex = sex;
this.idCard = '330xxxxxxxxxxxxxxx'
}
//定义方法
say():void{
console.log('hello')
}
// 静态成员,通过类名直接访问
static eat(food:string):void{
console.log(`吃${
food}`);
}
run():number{
console.log('跑了5公里');
return 5000;
}
}
//类的使用,通过new关键字来创建类的实例
let yannis:Person = new Person('Yannis', 28, 0);
console.log(yannis.name, yannis.age);// Yannis 28
yannis.say(); // hello
//用private修饰的类成员为私有成员,只能在类的内部使用
console.log(yannis.idCard);//报错:Property 'idCard' is private and only accessible within class 'Person'
//静态成员必须通过类名直接访问
yannis.eat('rice'); // 报错:Property 'eat' is a static member of type 'Person'
Person.eat('food') //`吃food
- 类的继承
类的继承是通过extends关键字来实现的,类的继承需要注意一下几点:
- 类的继承使用关键字 extends
- 子类除了不能继承父类的私有成员(private修饰)和构造函数,其它的都可以继承
- 一次只能继承一个类,不能同时继承多个类,但可以多重继承(如A继承B,B继承C)
- 如果子类显示的定义了构造函数,那么必须在子类的构造函数中通过super来调用父类的构造函数,否则会报错
- 子类中可以通过super关键字类使用父类中的成员
- 继承后,子类可以重写父类中的方法
class Son extends Person{
constructor(){
super("Alvin", 30, 1);//必须调用,并且父类的三个的参数也要传递,否则报错
super.say();//通过super关键字调用父类的say函数
this.surName = 'Li' //受保护的属性可被子类继承并且只能在子类内部使用
}
//子类重写了父类中的say方法
say():void{
console.log('hello father')
}
}
let son:Son = new Son();
console.log(son.name);
Son.eat('foot');
son.run();
son.say();//hello father
son.surName;//报错 protected修饰的成员可被子类继承但只能在子类的内部使用
通过上面代码我们发现:在子类中并没有定义任何属性和方法,但是父类中定义的除了private修饰的属性和方法外,其它成员子类都可以直接使用
存取器
在typescript中还可以通过getters/setters来截取类成员的访问,比如说有些字段是需要用户输入的,而为了校验数据的合法性,我们程序不能让用户随意输入,这时候就可以给类的成员设置一个存取器,存取器通过get和set来设置。
比如人的年龄应该是一个数字,并且年龄不能小于1也不能超过150,那么这个时候我们就可以把年龄(age)属性设置成私有属性,然后再通过存取器来对成员进行控制。
class Person{
private _age:number;
get age():number{
//这里就可以根据业务逻辑加一些内容
return this._age;
}
set age(a: number){
//这里就可以根据业务逻辑加一些校验
if(a<1 || a > 150) return;//或给出提示信息
this._age = a;
}
}
// 使用时通过 实例.属性名即可
let p = new Person();
p.age = 29;
抽象类
typescript跟其它后端强类型语言一样,它也有抽象类。抽象类有如下一些特征:
- 抽象类一般用作其它子类的基类使用(就是用于继承)
- 抽象类一般不会被直接实例化
- 抽象类需要使用abstract关键字定义
- 抽象类中可以定义普通成员方法,也可以定义抽象方法
- 通过abstract关键字定义的方法为抽象方法
- 抽象方法不能有具体的实现,也就是说只能声明成一个方法,并能有具体的实现
- 如果定义了抽象方法,那么子类继承后一定要实现这些抽象方法
abstract class Person{
abstract sayHi():void;//抽象方法,没有具体的实现
run():void{
console.log('she is running)
}
}
class Son extends Person{
//这里必须要实现抽象类Person中的数据。
sayHi():void{
console.log('hello');
}
}
总结
本文我们学习了typescript中的类,知道了什么是类,类是干嘛用的,如何定义一个类,以及类的一些特点,还用代码对类的描述做了展示。此外我们还学习了类的继承,类的成员访问修饰符以及抽象类。相信通过本次的学习,小伙伴们对ts中的类都有了更进一步了解了。
好了小伙伴们,本次分享就到这里了,喜欢的小伙伴欢迎点赞留言加关注哦~