一.Class类
1.class类-属性方法
1)简介:
类是用来 创建对象 模板。
同时类声明也会引入一个 新类型,可定义其 实例属性、方法和构造函数。
2)实例属性:
①用法:
class 类名{
//1.实例属性(字段)
//字段名、类型、初始值
字段名1:类型='xxx'
//可选字段可以不设置初始值
字段名2?:类型
//2.构造函数
//3.方法
}
//使用类 实例化对象 基于类 创建对象
//可选字段在使用时需要配合使用 可选链操作符 避免出错
const p:类名 = new 类名()
p.字段名1
p?.字段名2
②实例代码:
class Cat{
name:string = 'Tom'
foods?:string
}
//基于类,创建对象
let c:Cat = new Cat()
c.name = '河马'
console.log('姓名',c.name)
console.log('食物',c.foods?.length)
//这个问号的意义在于,如果food真的有值则取其长度,如果没有值就取food本身,即为空
let z:Cat = new Cat()
z.name = '荷花'
z.foods = '河马'
console.log('姓名',z.name)
console.log('食物',z.foods?.length)
2.class类-构造函数
1)简介:
不同实例,将来需要有不同的字段初始值,就需要通过构造函数实现。
2)基本语法:
class 类{
字段A:类型
字段B:类型
constructor(参数...) {
//通过new 实例化的时候 会调用constructor
//通过关键字this 可以获取到实例对象
this.字段A = 参数
}
}
const 实例化1 = new 类(参数...)
const 实例化2 = new 类(参数...)
3)基础实例代码:
class Food{
name:string
price:number
//希望有不同实例,有不同的字段初始值->构造函数
constructor(name:string,price:number) {
this.name=name
this.price=price
}
}
const f1 = new Food('西红柿鸡蛋',15)
const f2 = new Food('土豆炖鸡块',24)
console.log('名称:',f1.name,'价格:',f1.price)
console.log('名称:',f2.name,'价格:',f2.price)
4)进阶实例代码:
加入了一个interface接口,基于接口方便定义实例参数(无需按照顺序进行输入)
interface IFood{
name:string
price:number
desc:string
}
class Food{
name:string
price:number
desc:string
//希望有不同实例,有不同的字段初始值->构造函数
constructor(paramsObj:IFood) {
this.name=paramsObj.name
this.price=paramsObj.price
this.desc =paramsObj.desc
}
}
let p1:Food = new Food({
name:'西兰花',
desc:'好吃',
price:188
})
let p2:Food = new Food({
name:'黄瓜炒鸡蛋',
desc:'清爽',
price:3688
})
console.log('菜名:',p1.name,'价格:',p1.price,'描述:',p1.desc)
console.log('菜名:',p2.name,'价格:',p2.price,'描述:',p2.desc)
3.class类-定义方法&静态方法&静态属性
1)简介:
类中可以定义方法,并且在内部编写逻辑。
class 类名{
方法名(参数...):返回值类型{
//逻辑
//可以通过this获取实例对象
}
}
2)实例代码:
class Person{
name:string
constructor(name:string) {
this.name = name
}
//定义方法
sayHi(name:string){
console.log(`你好${name},我是:${this.name}`)
}
}
const p:Person = new Person('笨猪河马')
//方法调用
p.sayHi('可爱的荷花')
3)静态属性和静态方法:
①简介:
静态属性和静态方法不是给我们实例化对象添加的,是给类添加的,比如定义一个数字工具类中会有π=3.14,e=2.71
①语法:
class 类{
static 字段:类型
static 方法(){}
}
//使用
类.字段
类.方法()
②实例代码:
class Robot{
//如果不设置值,默认是undefined
static PI:number = 3.14
static version:string = 'v10.12'
//工具方法
static getRandomNumber(){
return Math.random()
}
}
//无需实例化对象,直接调用类 没有new 也可以直接用
console.log('机器人版本:',Robot.version)
console.log('生成一个随机数:',Robot.getRandomNumber())
console.log('计算半径为5的圆的面积:',Robot.PI*5*5)
4.class类-继承extends和super关键字
1)简介:
我们在实际使用中各个类之间往往会有很多相似之处,比如说猫和狗,都是动物,我们就可以定义一个动物类作为猫类和狗类的父类。比如程序员和教师都有姓名、年龄、家庭住址、email,只不过能做的职业功能不同,我们就可以添加一个人类(含有姓名、年龄、家庭住址、email四个属性)作为他们的父类。
即把公共部分抽取出来,进行复用,我们的代码就会更加简洁高效。
class 父类{
//字段
//方法
//构造函数
}
class 子类 extends 父类{
//自己的字段(属性)
//自己的方法
//可以重写父类的方法
}
2)实例代码:
class Person{
name:string
age:number
constructor(name:string,age:number) {
this.name=name
this.age=age
}
sayHi(){
console.log('大家好!','我叫',this.name,'今年',this.age,'岁')
}
}
class Student extends Person{
grade:string
constructor(name:string,age:number,grade:string) {
//父类中的构造函数需要我们手动调用,子类可以访问父类的实例字段、实例方法和构造函数
//此时需要手动调用super()构造函数,super.方法名() super.属性名
super(name,age)
//完成自己属性的初始化
this.grade=grade
}
//子类中想要重写父类的方法,只需要提供同名的方法即可
//比如学生想展示一下自己的英文水平
sayHi(): void {
console.log('Hello!','My name is',this.name,'Now year',this.age,',我的年级是',this.grade)
}
study(){
console.log('我是学生,我爱学点小习')
}
}
let s1:Student = new Student('河马',74,'大四')
s1.sayHi()
console.log('今年',s1.grade)
s1.study()
class Teacher extends Person{
}
let t1:Teacher=new Teacher('大卑老师',9999)
t1.sayHi()
class Worker extends Person{
}
let w1:Worker=new Worker('修水管的师傅',41)
w1.sayHi()
tips:关于super(),子类可以通过super访问父类的实例字段、实例方法和构造函数。
5.class类-instanceof和typeof
1)简介:
instanceof运算符可以用来检测某个对象是否是某个类的实例
typeof只能用于判断简单类型,如Boolean、string、number等简单类型
2)typeof实例代码:
console.log(typeof 111)
console.log(typeof true)
console.log(typeof 'abc')
class Person{
}
class Student extends Person{
}
let p:Person = new Person()
let s:Student = new Student()
console.log(typeof p)
console.log(typeof s)
我们在日志中会发现typeof判断简单类型都可以直接显示其类型,但用typeof去判断p和s会显示object
3)instanceof实例代码:
①需求:
定义一个父类→定义子类并继承父类→实例化子类并通过instanceof进行判断→判断数组是否为Array的实例
②代码:
class Person{
}
class Student extends Person{
}
class Worker{
}
let s:Student = new Student()
console.log('s和Student类的instanceof判断结果:',s instanceof Student)
console.log('s和Person类的instanceof判断结果:',s instanceof Person)
console.log('s和Worker类的instanceof判断结果:',s instanceof Worker)
③判断数组代码:
interface IObj{}
//判断一个变量是否存的是数组
let temp=[]
let temp2:IObj={}
//普通对象可以用数组判断
console.log('temp1是否是数组',temp instanceof Array)
//如果是调temp2这种接口里的方法就不能用数组去判断
console.log('temp2是否是数组',temp2 instanceof Array)
6.class类-类的修饰符
1)简介:
类的属性和方法可以通过修饰符来限制访问
修饰符包括:readonly、private、protected和public
省略不写默认为public
2)readonly实例代码:
class Cat{
name:string
age:number
readonly legs:number=4
constructor(name:string,age:number) {
this.name=name
this.age=age
}
}
let c1=new Cat('小花',2)
c1.name='小美'
c1.legs=6 //会报错
console.log('姓名',c1.name)
3)private实例代码:
class Person{
private name:string=''
private age:number=0
}
class Student extends Person{
sayHi(){
console.log('访问私有的数据:',super.name)
//私有数据无法在外部(子类)中访问
}
}
4)protected修饰符
①简介:
protected修饰符的作用与private修饰符非常相似
不同点是protect修饰的成员允许在派生类(子类)中访问
②代码演示:
class Person{
protected name:string=''
private age:number=0
}
class Student extends Person{
sayHi(){
console.log('访问私有的数据:',super.name)
}
}
用protected定义父类的name,一样的代码就可以访问了。
但是在外部访问,一样不允许访问。
class Person{
protected name:string=''
private age:number=0
constructor(name:string,age:number) {
this.name=name
this.age=age
}
}
class Student extends Person{
sayHi(){
console.log('访问私有的数据:',super.name)
}
}
let s1:Student =new Student('小华',18)
//外部
console.log('外部访问保护的数据:',s1.name)