一、类型别名
类型别名,顾名思义就是给某个类型起别名,之后就可以通过这个别名来使用类型。用法如下:
// 语法: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)
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)
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('紫光')
4.静态属性、方法
类还可以添加静态属性、方法,后续访问需要通过 类 来完成。
!!!注意点:
- 静态方法中不能使用实例属性和实例方法
- 静态方法中使用静态属性和静态方法时,用法: 类名.属性 或者 类名.方法()
// 定义
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())
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()
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()
小练习:
- 请使用类的静态方法定义出一个随机颜色生成的方法,并调用
- 请使用类的实例化写法定义出如下:
- 定义父类 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()
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)
【补充】typeof运算符
可以通过 typeof 运算符来获取类型,他返回的是一个类型字符串 !!!注:对象、数组、null获取到的都是 object
console.log(typeof 123)
console.log(typeof '123')
console.log(typeof false)
console.log(typeof undefined)
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]