HarmonyOS NEXT零基础入门到实战-第三部分

Class类-属性方法(字段)
Class类
类是用于 创建对象 模板。 同时类声明也会引入一个 新类型,可定义其 实例属性、方法和构造函数。
学习目录:
1、Class类 实例属性
// 定义类名
class Cat {
  name: string = 'Tom'
  foods?: string
}

// 基于类,创建对象
let p: Cat = new Cat()
console.log('姓名:', p.name)
// ?.  ==> 可选链操作符 如果p.foods真有值,那就取length,如果没有值就取的是foods本身,不调用length
console.log('食物:', p.foods?.length)
p.foods = '小黄鱼'
console.log('食物:', p.foods?.length)

2、Class类 构造函数
3、Class类 定义方法
// 定义类名
class Cat {
  // 1、定义属性、变量
  name: string = 'Tom'
  foods?: string
}

// 基于类,创建对象
let p: Cat = new Cat()
// console.log('姓名:', p.name)
// ?.  ==> 可选链操作符 如果p.foods真有值,那就取length,如果没有值就取的是foods本身,不调用length
// console.log('食物:', p.foods?.length)
p.foods = '小黄鱼'
// console.log('食物:', p.foods?.length)

// 简易用接口
interface IFood {
  name: string
  price: number
  desc: string
}

// 复杂用class
class Food {
  name: string
  price: number
  desc: string

  // 2、构造方法 希望不同的实例,有不同的字段初始化值  --> 构造函数
  constructor(paramsFood: IFood) {
    this.name = paramsFood.name
    this.price = paramsFood.price
    this.desc = paramsFood.desc
  }

  // 3、定义方法
  printFoods(): string {
    console.log('printFoods: name:',this.name, ",price:", this.price, ",desc:" ,this.desc)
    return 'printFoods: name:' + this.name + ",price:" + this.price + ",desc:" + this.desc
  }
}

let f1: Food = new Food({
  name: '西兰花',
  price: 2,
  desc: '好吃'
})

let f2: Food = new Food({
  name: '黄瓜',
  price: 5,
  desc: '清爽'
})

console.log('f1:',f1.printFoods())
console.log('f2:',f2.printFoods())

4、静态属性 和 静态方法
// 存取版本号、工具方法
class Rebot {
  // 静态属性和静态方法
  static version: number = 1.0

  static getRandom(): number {
    return Math.random()
  }
}
console.log('version:', Rebot.version)
console.log('getRandom():', Rebot.getRandom())

5、继承 extends 和 super 关键字
类可以通过 继承 快速获取另一个类的 字段 和 方法
// 父类  子类
// 人类  学生、老师、工人
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(name, age)
    // 完成自己的属性初始化
    this.grade = grade
  }
  
  study() {
    console.log('我是学生,我爱学习')
  }
  sayHi() {
    super.sayHi()
    console.log('Hello Nice to Meet you')
  }
}
let s1 = new Student('Tom', 20, '三年级')
s1.sayHi()
console.log(s1.grade)
s1.study()

class Teacher extends Person {

}
let s2 = new Teacher('TomTeacher', 21)
s2.sayHi()

class Worker {
}

6、instanceof 检测是否实例
typeof 基础类型  instanceof 对象类型
console.log(typeof 111)
console.log(typeof true)

class Person{}
class Student extends Person{}
class Worker extends Person{}
let p = new Person()
let s = new Student()
console.log(typeof p)  // object
console.log(typeof s)  // object
// typeof 仅能用于判断简单类型 复杂类型则需用instanceof判断

console.log('判断结果:', p instanceof Person)  // true
console.log('判断结果:', s instanceof Student) // true
console.log('判断结果:', s instanceof Person)  // true
console.log('判断结果:', s instanceof Worker)  // false

interface IObj{}
// 判断一个变量是不是数组类型
let temp = []
console.log('判断结果:', temp instanceof Array)  // true
let iObj: IObj = {}
console.log('判断结果:', iObj instanceof Array)  // false

7、修饰符 (readonly 、 private、protected)
protected:派生类/子类可以访问
private:只有自己类内部可以自己访问 其它均不能访问
源代码:
  age: number
  // 可读不能修改
  readonly legs: number = 4

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

let c1 = new Cat('小花', 2)
// c1.legs = 6 // 不能修改


class Person{
  private name:string = ''
  private age:number = 0
  desc: string = ''
  sayHi() {
    // private:内部可以访问
    console.log(this.name)
  }
}
let p1 = new Person()
console.log(p1.desc)  // 无法在外部访问私有数据
class Student extends Person{
  sayHi(){
    console.log(super.desc)  // 私有数据子类无法访问
  }
}

8、剩余参数 和 展开运算符
// ...数组名 ===> 可以收集剩余的参数
function sum(n1:number, n2:number, ...argsArr: number[]): number {
  let total = n1 + n2
  // 遍历剩余的参数,如果有剩余的参数,就继续累加
  for(let temp of argsArr) {
    total+= temp
  }
  console.log('结果', total)
  return total
}

console.log('1+2的和:' + sum(1,2))
sum(1,2,3,4,5,6,7)

// ArtTs中 展开运算符只能是合并数组的
let ar1:number[] = [1,2,3]
let ar2:number[] = [4,5,6]
let newArr:number[] = [...ar1, ...ar2]
console.log('最终的数组', newArr)

interface接口的继承和实现
接口继承使用的关键字是extends
源代码:
interface IAnimal {
  name: string
  age: number
}

interface IDog extends IAnimal {
  color: string
}
interface ICat extends IAnimal {
  hair: string // 毛发
}

let dog1: IDog = {
  name: '小泰迪',
  age: 2,
  color: '棕色'
}

console.log('dog:', dog1.name)

接口的实现:
可以通过接口结合 implements 来限制 类 必须要有 某些属性 和 方法
// 定义一个接口,约束类  ---》 类需要按照接口的需求,实现类的主体
interface IDog {
  name: string
  age: number
  jump: () => void
}

// 基于接口,实现类
class Dog implements IDog {
  name: string
  age: number

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

  jump() {
    console.log('jump')
  }
}

let dog1 = new Dog('小黑', 1)
dog1.jump()


==================================
泛型:
泛型可以让函数等,与多种不同的类型一起工作,灵活可复用
通俗一点就是:类型是 可变 的

泛型函数
// 封装一个函数:传入什么样的参数,就立刻返回什么样的参数
function fn<T> (param: T) : T {
  return param
}

fn<string>('abc')
fn<number>(1)
fn<boolean>(false)
fn<number[]>([1,2,3,4,5])

// ArtTs 会根据默认根据传参,进行类型推断,动态的配置 T 类型参数 的值
// 练习1:定义一个函数,参数是数组(存的类型不定),返回数组的长度
function getLength<T> (arr: T[]) : number {
  return arr.length
}

console.log('数组长度:', getLength<number>([1,2,3]))
console.log('数组长度:', getLength<string>(['a']))

// 练习1:定义一个函数,参数是数组(存的类型不定),返回数组的最后一项
function getLast<T> (arr: T[]) : T {
  return arr[arr.length - 1]
}
console.log('数组最后一项:', getLast<number>([1,2,3,99]))

泛型约束
之前的类型参数,可以传递任何类型,没有限制。
如果希望有限制 --->  泛型约束。
// 泛型约束: 给传递的参数类型,添加限制
interface ILength {
  length: number
}

function fn<T extends ILength>(param : T) {
  console.log('', param.length)
}

fn<string>('123')
fn<number[]>([1,2,3,4])

class Desk {
  length = 2
}

let d = new Desk()
fn(d)

多个泛型参数
// 多个泛型参数
function fn<T1,T2> (param1: T1, param2: T2) {
  console.log('参数1:', param1, ', 参数2:', param2)
}
fn('abc', false)
fn(['abc', 'def'], false)
fn(['abc', 'def'], [1,2,3,4])

泛型接口/泛型类
// 泛型接口
// 定义接口的时候,结合泛型定义,就是泛型接口。
interface  IdFunc<T> {
  // 约定两个方法(id类型不定, string number)
  // 1、传入 id 值, 就返回 id 值
  // 2、返回一个 ids 数组
  id: (value: T) => T
  ids: () => T[]
}

let obj:IdFunc<number> = {
  id(value: number) {
    return value
  },
  ids() {
    return [1,2,3]
  }
}

// 泛型类
// 定义类的时候,结合泛型定义,就是泛型类
class Person<T> {
  id: T

  constructor(id: T) {
    this.id = id
  }

  getId() : T {
    return this.id
  }
}

let person: Person<number> = new Person<number>(1)
console.log('personId:', person.getId())


===== 
模块化语法:
1、模块化基本认知
模块化:把一个大的程序,【拆分】成若干的小的模块,通过【特定的语法】,可以进行任意组合。
ArkTS中的每个 ets文件,都可以看做是一个模块

2、默认导入和导出
默认导出:指一个模块,只能默认导出的 一个值或对象。使用时,可以 自定义 导入名称。
使用步骤:
1、当前模块中 导出模块。
2、需要使用的地方 导入模块。
// 默认导出
export default 需要导出的内容
// 默认导入
import xxx from '模块路径'

源代码:
module1.ets:

interface Person {
  name: string
  age: number
}
// 一个ets 文件,就是一个模块,每个模块之间独立
let num: number = 10
let person: Person = {
  name: 'json',
  age: 18
}

// 默认导出(导出一个值)
// export default num
export default person

module2.ets:
const fn = ()=> {
  console.log('hello world')
}
export default fn

index.ets:
// 路径: 查找文件时,从起点到终点的路线
// 相对路径:从当前文件出发查找目标文件
// -> 找上一级 ../
// -> 找同级目录 ./
import num from '../tools/module1'
import fn from '../tools/module2'

console.log('module1 中的数据:', JSON.stringify(num))

// 函数
fn()

3、按需导入和导出
按需导出:指的是一个模块,可以按照需要,导出多个特性。
export  {name1, name2, ..., nameN};
import {name1, name2, name3 as 别名} from "module-name"

module3.ets:
// 按需导出
// 多个特性,逐个 export 按需导出
let name1: string = '刘备'
let price: number = 9.98
let sayHi = () => {
  console.log('打招呼啊')
}


// 一次性将对各特性,进行导出
export {name1, price, sayHi}

index.ets: 部分代码
// 按需导入 
import {name1, price, sayHi as sayHello} from '../tools/module3'

console.log('module1 中的数据:', JSON.stringify(num))

// 函数
fn()

console.log('module3中的数据:', name1, price)
sayHello()

4、全部导入
export {name1, name2, ...}
import * as Module3 from  '../tools/module3'
console.log('全部的数据', Module3.name1)
 

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值