类
类声明引入一个新类型,并定义字段,方法和构造函数
属性 必须要给初始值
constructor():构造函数
定义类后,可以使用关键字new创建实例
export class PersonStudent{firstName:string=''//名lastName:string=''//姓//constructor():构造函数:给属性初始值,初始化属性// constructor() {// console.log('无参函数')// }constructor(firstName:string='',lastName:string='') {this.firstName=firstNamethis.lastName=lastName}//函数,不能写functionfullName(){//this调用自己的属性return this.lastName+this.firstName}
}
字段
字段时直接在类中声明的某种类型的变量
类可以具有实例字段或者静态字段
实例字段
要访问实例函数,需要使用类的实例
//实例字段
let p:PersonStudent=new PersonStudent('z','s')
//实例字段,通过new对象之后进行访问的字段
p.firstName='啧啧啧';
静态函数
使用关键字static将字段声明为静态。
要访问静态字段,需要使用类名
构造函数不允许使用静态字段
class person3{//静态字段:staticstatic firstName:string=''lastName:string=''// static constructor() {// }
}
静态函数
不支持this,无法直接访问非静态字段/函数
静态字段使用类名进行访问
class person3{a2(){}a3(){this.a2()}//静态函数static a(num1:number,num2:number){person3.firstName='张三'//不支持this,无法直接访问非静态字段/函数// this.lastName='aa'//无法直接访问函数// a2();return num1+num2}
}
//不用new对象进行访问
person3.firstName='ss'
//静态访问a()
person3.a(1,2)
继承
一个类可以继承另一个类·,继承类继承父类的字段和方法,但不继承构造函数。继承可以新增定义字段和方法,也可以覆盖其父类的方法
继承extends
子类 只支持单继承(只能继承一个父类)
必须调用父类的有参的构造函数,构造函数必须调用,但不能继承
关键字super可用于访问父类的实例字段、实例方法和构造函数。在实现子类功能时,可以通过该关键字从父类中获取所需接口
//父类
class Pet{name:string=''sex:string=''static age:number=0constructor(name:string,sex:string) {this.name=namethis.sex=sex//不能使用静态 static age:number=0}//函数show(){return `昵称:${this.name},性别:${this.sex}`}
}
//子类
class Dog extends Pet{constructor(name:string,sex:string) {//关键词:supersuper(name,sex)}//子类自己的属性type:string=''//重写show(){//方法不一样,结果一样return super.show()+'品种:'+this.type// return `昵称:${this.name},性别:${this.sex},品种:${this.type}`}a(){this.show()//子类super.show()//父类}
}
let pe=new Pet('张三','男')
//当子类的函数和父类的函数重名,会调用子类的函数
pe.show()
重写
子类重写父类的函数
要求:1.方法名相同
2.参数类型相同
3.返回值类型相同,或者其子类
show(){return super.show()+'品种:'+this.typereturn `昵称:${this.name},性别:${this.sex},品种:${this.type}`}
重载
同一个类中,方法名相同,参数列表不同,返回值类型相同
class Over{//重载aa(x:number):voidaa(x:string,k:number):voidaa(x:number|string,k?:number):void{}
}
class Oo extends Over{aa(x:number):voidaa(x:string):voidaa(x:number|string):void{}
}
可见性修饰符
public修饰的类成员在程序的任何可访问该类的地方都是可见的
private修饰的成员不能再声明该声明的类之外访问
protected修饰符的作用与private修饰符非常相似,不同点是protected修饰的成员允许在子类中访问
class Aa{//public:共有的public a1:string=''// protected 受保护的:本类和子类中使用protected a2:string=''//private私有的private a3:string=''}
class Bb extends Aa{show(){this.a2='asd'}
}
let aa=new Aa()
let bb=new Bb()
aa.a1;
getter和setter可以用提供对对象属性的受控访问
//可见性修饰
class pri{private _a1: stringpublic set a1(value: string) {this._a1 = value}public get a1(): string {return this._a1}private _a2: stringpublic set a2(value: string) {this._a2 = value}public get a2(): string {return this._a2}constructor(a1: string, a2: string) {this._a1 = a1this._a2 = a2}}
let p1=new pri('1','2');
p1.a1='a'
Record类型的对象字面量
泛型Record<k,v> 键值对
let map:Record<string,string>={'name':'张三','sex':'男','color':'黄'
}
let names=map['name'];
class Stu{name:string=''age:number=0
}
//Record 存数据,键值对数据
let map2:Record<string,Stu>={'张三':{name:'张三',age:18},'李四':{name:'李四',age:18},'李五':{name:'李五',age:18},'李六':{name:'李六',age:18},'李其':{name:'李其',age:18},
}
let s:Stu=map2['张三'];
接口
接口声明引入新类型,接口是定义代码协定的常见方式
接口通常包含属性和方法的声明
//接口
interface Stus{//接口中的方法,没有方法体(方法的实现)eat():voidstudy():number
}
//(实现类)实现接口,必须重写接口中的方法
class Stu1 implements Stus{eat(): void {console.log('学生在吃')}study(): number {console.log('学生在学习')return 100}
}
接口属性
接口的属性会在实现类中默认隐式生成getter/setter方法
interface Stu2{name:stringsex:stringeat():voidstudy():number
}
class Stu3 implements Stu2{name: string=''sex: string=''eat(): void {throw new Error('Method not implemented.')}study(): number {throw new Error('Method not implemented.')}}
let stu3=new Stu3()
stu3.name='123'
接口继承
接口可以继承其它接口
继承接口包含被继承接口的所有属性和方法,还可以添加总结的属性和方法
interface Inte1{a():void
}
interface Inte2 extends Inte1{b():void
}
class Imp1 implements Inte2{b(): void {throw new Error('Method not implemented.')}a(): void {throw new Error('Method not implemented.')}
}
实现多个接口
interface A1{a():void
}
interface B1{b():void
}
class C1 implements A1,B1{b(): void {throw new Error('Method not implemented.')}a(): void {throw new Error('Method not implemented.')}}
多态的实现方法,同一个方法在不同条件得到不同的结果
继承中的多态
接口实现的多态和继承实现的多态没有区别
class Pet{//父类name:string=''play():void{console.log('玩耍')}
}
class Dog extends Pet{//子类play():void{console.log('狗踢皮球')}
}
class Cat extends Pet{//子类play():void{console.log('猫玩狗')}
}
// 1.以父类作为形参
function play(pet:Pet){pet.play()
}
play(new Cat())
play(new Dog())
// 2.以父类作为返回值
function ly():Pet{let num=Math.random()*10if(num>5){return new Dog()}else {return new Cat()}
}
泛型
泛型类型和函数允许创建的代码在各种类型上运行,而不仅支持单一类型
泛型的通配符
泛型 T:type类,
K:key ,
V:value,
E:element集合,
N:number
?:不确定的类型
class Fx<E>{a(e:E):void{console.log(`${e}`)}
}
let fx=new Fx<number[]>();
fx.a([1,2])
泛型函数
//返回数字数组的最后一个元素
function lastGet(x:number[]):number{return x[x.length-1]
}
//调用
let aa=lastGet([1,2,3,4])
//返回任意类型数组的最后一个元素
function getLast<T>(x:T[]):T{return x[x.length-1]
}
//调用
let a2=getLast<string>(['1','2','as'])
空安全
非空断言运算符
应用于可空类型的值时,它编译时类型变为非空类型
export class A{a:number=0
}
export function fc(aa:A|null){// aa?.a=9console.log(`${aa!.a}`)//非空断言}
空值合并运算符
空值合并二元运算符??用于检查左侧表达式的求值是否等于null或者undefined,
如果是,则表达式的结果为右侧表达式,否则,结果为左侧表达式
export function hb(str:string|null){// return (str!=null && str!=undefined)?str:'asd'//如果结果是null或undef,结果会是'asd'return str ?? 'asd'
}
可选链
在访问对象属性时,如果该属性是undefined或者null,可选链运算符会返回undefined。
export class A{a:number=0
}
export function fc(aa:A|null){// aa?.a=9//可选链console.log(`${aa?.a}`)}
导出:export
静态导入
导入声明用于导入其他模块导出的实体,并在当前模块中提供其绑定,导入声明由两部分组成
1.导入路径,用于指定导入的模块
2.导入绑定,用于定义导入的模块中的可用实体集和使用形式
动态导入
import()语法通常称为动态导入,是一种类似函数的表达式,用来动态导入模块
as 别名,把A改为aaa
import { promptAction } from '@kit.ArkUI';//导入kit下单个模块接口
并发
在同一时间内,存在多个任务同时执行的情况。
对于多核设备,这些任务可能同时在不同cpu上并行执行
对于单核设备,多个并发任务不会在同一时刻并行执行
为了提升应用的响应速度与帧率,避免耗时任务对主线的影响,arkts提供了异步并发和多线程并发
异步并发
promise和async/await提供异步并发能力,是标准的JS异步语法
console.log('任务1');setTimeout(() => {console.log('任务2'); }, 2000);console.log('任务3');console.log('任务4');console.log('任务5');console.log('任务6');console.log('任务7');
异步语法是一种编程语言的特性,允许程序在执行某些操作时不必等待其完成,而是可以继续执行其他操作
回调地狱
setTimeout(() => {console.log(Math.random() + '');setTimeout(() => {console.log(Math.random() + '');setTimeout(() => {console.log(Math.random() + '');setTimeout(() => {console.log(Math.random() + '');setTimeout(() => {console.log(Math.random() + '');}, 1000);}, 1000);}, 1000);}, 1000);}, 1000);
Promise
Promise是一种用于处理异步操作的对象,可以将异步操作转换为类似于同步操作的风格,以方便代码编写和维护。
promise有三种状态:
1.pending:进行中
2.fulfilled:已完成
3.rejected:已拒绝
promise对象创建后处于pending状态,并在异步操作完成后转换为fulfilled或rejected
//promise //resolve:成功,reject:失败let p1=new Promise((resolve,reject)=>{// 生成随机数,小于0.5失败,大于0.5成功let num=Math.random()if(num<0.5){reject('小于0.5')}else{resolve('成功:'+num)}});p1.then(data=>{console.log(data);}).catch(err=>{console.log(err);}).finally(()=>{console.log('最终执行');})
then用来处理resolve(成功)的数据 data成功后返回的数据
catch用来处理reject(失败)的数据 err失败后返回的数据
async
async函数 达到的效果是同步代码的效果
function a(){}function b(){}function c(){}function d(){}function e(){a()b()c()d()}e()
async函数是一个返回promise对象的函数,用于表示一个异步·操作,在async函数内部,可以使用await关键字等待一个promise对象的解析,并返回解析值
模拟一个以同步执行异步操作的场景
// 1.生成一个promisefunction p(){return new Promise((r,j)=>{setTimeout(() => {let num=Math.random()if(num>0.5){r(num)}else{j(-1)}}, 1000);})}// 使用异步函数async function asy() {console.log('开始执行异步操作');try{let num1=await p()console.log(num1);let num2=await p()console.log(num2);} catch(error){console.log(error);}}console.log('主线程任务开始');asy()
此操作在DevEco Studio中使用
export function p():Promise<number>{return new Promise((r,j)=>{setTimeout(() => {let num=Math.random()if(num>0.5){r(num)}else{j('拒绝,你是个好人')}}, 1000);})
}
export async function asy() {console.log('开始执行异步操作');try{let num1=await p()console.log(num1.toString());let num2=await p()console.log(num2.toString());} catch(error){console.log(error);}
}
asy()