鸿蒙应用开发-类型别名、类、剩余和展开

228 阅读6分钟

一、类型别名

类型别名,顾名思义就是给某个类型起别名,之后就可以通过这个别名来使用类型。用法如下:

 // 语法:type 别名 = 类型
type lenght = number | string |number[] | string[] | boolean |Color

let q :lenght = 1
let w :lenght = '1'
let e :lenght = [1]
let r :lenght = ['1']
let t :lenght = true
let y :lenght = Color.Black

二、类

类是用于创建对象的模板。他们用代码封装数据以处理该数据。同时类声明也会引入一个新类型,并定义其字段方法构造函数。用法:

// 类名 首字母大写(规范)
class 类名{
  // 属性
  
  // 方法
  
  // 构造函数
}
// 使用类 实例化对象 基于类 创建对象
const x:类名 = new 类名()

1. 实例属性

// 类名
class XmPerson{
  name:string = '小明' // 字段名+类型+初始值
  age:number = 20  // 注:可选字段可以不设置初始值
}

let xm:XmPerson = new XmPerson()
console.log(xm.name,xm.age)

实例属性.png

2. 构造函数

class Person{
  name:string
  age:number
   // constructor(参数...) {
    // 通过 new 实例化的时候 会调用 constructor
    // 通过关键字 this 可以获取到实例对象
  // }
  constructor(pname:string,page:number) { // 通过 new 实例化的时候 会调用 constructor
    this.name = pname
    this.age = page
  }
}

let xm:Person = new Person('小明',18)
console.log(xm.name,xm.age) 
let xq:Person = new Person('小强',20)
console.log(xq.name,xq.age)

构建函数.png

3. 实例方法

在类中可以定义 方法 ,并且在内部编写逻辑。

class Person{
  name:string

  constructor(pname:string) {
    this.name = pname
  }
  //方法名(参数...):返回值类型(类型可写可不写){
    // 逻辑...
    // 可以通过 this 获取实例对象
  //}
  dance(){
    console.log(this.name,'跳起舞来')
  }
  
  sing(song:string){
    console.log(this.name,'唱歌:',song)
  }
}
let xm:Person = new Person('小明')
xm.dance()
xm.sing('紫光')
let xh:Person = new Person('小红')
xh.dance()
xh.sing('紫光')

实例方法.png

4.静态属性、方法

类还可以添加静态属性、方法,后续访问需要通过 类 来完成。

!!!注意点:

  1. 静态方法中不能使用实例属性和实例方法
  2. 静态方法中使用静态属性和静态方法时,用法: 类名.属性 或者 类名.方法()
// 定义
class 类{
  static 字段:类型
  static 方法(){}
}

// 使用
类.字段
类.方法()
//定义
class  Tools {
  static Pi:number = 3.1415926
  static getRandom(){
    return Math.random()
  }
}
//使用
console.log(Tools.Pi.toString())
console.log(Tools.getRandom().toString())

静态方法.png

5.继承

类可以通过 继承 快速获取另外一个类的 字段方法。 并且还可以扩展属于自己的字段和方法加强父类没有的能力。

//父类
class Person{
  name:string
  age:number

  constructor(name:string,age:number) {
    this.name = name
    this.age = age
  }

  sayHi(){
    console.log('说话')
  }
}
//子类   继承父类
class student extends Person{
  //扩展
  classNo:string = '2班'
  len(){
    console.log('学习')
  }
  //重写 父类
  sayHi(){
    console.log('普通话')
  }
}

let xm:student = new student('小明',20)
console.log(xm.classNo,xm.name,xm.age)
xm.len()
xm.sayHi()

继承.png

6.super 关键字

子类通过 super 可以访问父类的实例字段、实例方法和构造函数。 常用方法:通过super类调用父类的构造函数进行属性值的显示调用初始化。

!!!注意点:super调用父类的构造函数进行父类中的实例属性初始化,只能写在子类的constructor中的第一行

//父类
class Person{
  name:string
  age:number

  constructor(name:string,age:number) {
    this.name = name
    this.age = age
  }

  sayHi(){
    console.log('说话')
  }
}
//子类   继承父类
class student extends Person{
  classNo:string = '2班'

  constructor(name:string,age:number,classNo:string) {
    super(name,age) 
    this.classNo = classNo
  }

  len(){
    super.sayHi()
    console.log(this.name+'学习')
  }
}

let xm:student = new student('小明',20,'2班')
console.log(xm.classNo,xm.name,xm.age)
xm.len()

super关键词.png

小练习:

  1. 请使用类的静态方法定义出一个随机颜色生成的方法,并调用
  2. 请使用类的实例化写法定义出如下:
  • 定义父类 Dog -> 有属性name,age,毛发颜色,有一个方法,sayHi()->里面输出一个自我介绍 【狗叫做xxx,今年xx岁,毛发是xxx颜色】
  • 定义子类 sonDog -> 继承自父类 Dog,自己扩展出一个玩具名属性 toy,使用构造函数初始化toy属性值的同时还使用父类构造函数初始化name,age,毛发颜色,最后重写sayHi,介绍中输出【狗叫做xxx,今年xx岁,毛发是xxx颜色,我喜欢的玩具叫:xxx】
//1.随机颜色
class randomColor{
  static randomcolor(){
    let r:number = Math.floor(Math.random()*256)
    let g:number = Math.floor(Math.random()*256)
    let b:number = Math.floor(Math.random()*256)
    return `rgb(${r},${g},${b})`
  }
}

console.log(randomColor.randomcolor())
//2.
//父类
class Dog {
  name:string
  age:number
  color:string

  constructor(name:string,age:number,color:string) {
    this.name = name
    this.age = age
    this.color = color
  }
  sayHi(){
    console.log(`狗叫做${this.name},今年${this.age}岁,毛发是${this.color}颜色`)
  }
}
let dog:Dog = new Dog('大黄',3,'黄色')
dog.sayHi()
//子类
class sonDog extends Dog{
  toy:string

  constructor(name:string,age:number,color:string,toy:string) {
    super(name,age,color)
    this.toy = toy
  }
  sayHi() {
    console.log(`狗叫做${this.name},今年${this.age}岁,毛发是${this.color}颜色,狗喜欢的玩具叫:${this.toy}`)
  }
}

let sondog:Dog = new sonDog('小黄',0.5,'黄色','皮球')
sondog.sayHi()

练习.png

7. instanceof

instanceof 运算符可以用来检测某个对象是否是某个类的实例

class Father{
  name:string = ''
}
class Son extends Father{}

let son:Son = new Son()
console.log('son是否属于Father',son instanceof Father)
console.log('son是否属于Son',son instanceof Son)
console.log('son是否属于Scroller',son instanceof Scroller)

instanceof的使用.png

【补充】typeof运算符

可以通过 typeof 运算符来获取类型,他返回的是一个类型字符串 !!!注:对象、数组、null获取到的都是 object

console.log(typeof  123)
console.log(typeof  '123')
console.log(typeof  false)
console.log(typeof  undefined)

typeof的使用.png

8. 修饰符

(1) eadonly(只读)

readonly 的意思是只读,可以用来修饰属性(字段),修饰之后外部只可以取值,无法修改

(2) private(私有)

private修饰的成员不能在声明该成员的类之外访问,包括子类

(3) protected(受保护)

protected修饰符的作用与private修饰符非常相似,不同点是protected修饰的成员允许在派生类(子类)中访问

(4) public(公共)

public修饰的类成员(字段、方法、构造函数)在程序的任何可访问该类的地方都是可见的。

class Father{
  readonly legsNum:number = 2 // 只读,不可修改
  private wife:string = '老婆' // 私有 ,子类和其他类均不可使用
  protected money:number = 100000 //受保护的,
  public name:string = '' //公共 public可写可不写
}

小总结:

修饰符名作用适用范围访问限制
readonly只读属性无限制
private私有属性、方法类内部可以访问
protect保护属性、方法类及子类可以访问
public公共属性、方法无限制

三、剩余和展开

剩余参数

通过剩余参数的语法,我们可以将 函数方法 中一个不定数量的参数表示为一个数组。

!!! 剩余参数只能写在最后一位

// 剩余参数只能写在最后一位
function 函数名(参数1,参数2,...剩余参数数组){
  // 逻辑代码
  // 剩余参数之前的参数 挨个获取即可
  // 剩余参数:以数组的形式获取
}
//例子
function sum(numA:number,numB:number,...theArgs:number[]) {
  let total = numA+numbB;
  for (const arg of theArgs) {
    total += arg;
  }
  return total;
}

console.log(sum(1, 2, 3).toString()) // 6

console.log(sum(1, 2, 3, 4).toString()) // 10

展开

出于程序稳定性,以及运行性能考虑,在 ArkTS 中 ...(展开运算符) 只能用在数组上(对象数组也可以)。

const numArr1: number[] = [1, 2, 3, 4]
const numArr2: number[] = [5, 6, 7]

// 合并到一起
const totalArr: number[] = [...numArr1, ...numArr2] //[1,2,3,4,5,6,7]