鸿蒙-part3-arkts下

一 类

  • TypeScript 核心规则是要求,实例化后每个属性都有确定的值
  • 至于这个值从哪里来(构造函数、默认值、可选),它不管。

1.1 类的声明

js 复制代码
class Person {
   // 实例属性
   public name: string = '' // public可以省略, 实例变量需要初始值
   public subName: string = '' // public可以省略, 实例变量需要初始值
   public age?: number; // number| undefined
   
   // 构造方法
   constructor (name: string, subName: string) {
      this.name = name;
      this.subName = subName;
   }
   
   // 实例方法 在类中声明方法,不加 function
   function fullName(): string {
      return this.name + ' ' + this.subName
   }
}

1.2 类的初始化

js 复制代码
class Point {
  x: number = 0; 
  y: number = 0;
}

// 1 new 创建实例
let p = new Person();

// 2 字面量创建实例
let p1: Person = {x: 30, y: 20 };

1.3 静态属性

js 复制代码
class Person {
 public static personNumber: number = 0 // 静态变量
 
 constructor() {
   Person.personNumber ++
 }
}

let num = Person.personNumber

1.4 字段初始化

js 复制代码
class Person {
  name?: string; // 不需要 前面家let
  
  setName(newName: string) {
    this.name = newName;
  }
  
  getName():string | undefined  {
    return this.name;
  }
}

let n = new Person()
n.gatName()?.lenth // 编译成功

1.5 getter / setter

  • 注意:arkTs 声明实例变量,不会自动生成getter/setter方法
js 复制代码
class Person {
  _age: number = 0;
  
  set age(newAge: number) {
  
    if(newAge < 0 ) {
      throw Error('年龄不能小于0!')
    }
    this._age = newAge;
  }
  
  get age():number {
    return this._age;
  }
}

let jack = new Person();
jack.age = -22; // 访问get方法,非访问_age;
jack.age; // 访问get方法,非访问_age;

1.6 实例方法 静态方法

  • 类中的方法,不需要添加function
js 复制代码
class Person {
  name: string = ''
  eatChild() {

  }
  
  static eatFood() {
  
  }
}

1.7 类继承, 接口继承

  • 父类:基类
  • 子类:派生类
  • 继承类继承基类的字段和方法,但不继承构造函数
js 复制代码
class Father {

}

class Sun extends Father {

}
js 复制代码
interface DataInterface {
  new(): string;
}

class myData implement DataInterface {
    new(): string {
       return '我实现了哈~';
    }
}

1.8 构造函数,访问父类

js 复制代码
class Person {
  name: strinh = '';
  age: number = 0;
  
  constructior(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

class Son extends Person {
  height: number = 0
  constructor(height: number, name: string, age: number) {
    super(name,age) // 调用父类
    this.height = height;
  }
}

1.9 可见性修饰符

修饰符 类内部 子类(继承) 类外部
public 公开 ✅ 可访问 ✅ 可访问 ✅ 可访问
protected 受保护 ✅ 可访问 ✅ 可访问 ❌ 不可访问
private 私有 ✅ 可访问 ❌ 不可访问 ❌ 不可访问

1.10 对象字面量

  • 当创建实例为类时候,代替new表达式
  • 对象字面量只能,在可以推导出该字面量类型的上下文中使用
js 复制代码
class Person {
   name: string = '';
   age: number = 0;
}

let p:Person = {name:'jack', age: 13}; // 对象字面量,注意要加属于的类型

// 在数组中使用

let arr:Person[] = [{name: 'jack', age: 12}, {name: 'lucy', age: 11}];

1.11 Record类型 的对象字面量

  • 在第一章介绍

1.12 抽象类 abstract

  • interface接口:定规矩(轻量级),支持多继承
  • abstract抽象方法:定规矩 + 公共代码(字段,构造函数及公共方法),单继承

抽象方法 vs 普通方法

对比 抽象方法 普通方法
有没有方法体 ❌ 没有(; 结尾) ✅ 有({ ... }
子类必须实现 ✅ 必须重写 ❌ 可以不重写,直接用
能不能直接调用 ❌ 不能(没有实现) ✅ 能
在抽象类里 ✅ 可以 ✅ 可以
在普通类里 ❌ 不可以 ✅ 可以
js 复制代码
// 定义抽象类

abstract class Shape {
  // 定义普通实例变量
  color: string;
  
  // 定义普通构造方法
  constructior(color: string) {
    this.color = color;
  }
  
  // 定义普通方法
  showColor() {
    console.log('颜色 ---- ${this.color}');
  }
  
  // 定义抽象方法, 要求子类强制实现
  abstract area(): number;
}
js 复制代码
// 继承抽象类

class Rect: extends Shape {
  width: number = 0;
  height: number = 0;
  
  constructior(color: string, width: number, height: number) {
    super(color);
    this.width = width;
    this.height = height;
  }
  
  area(): number {
    return this.width * this.height;
  }
}

二 接口 interface

  • 接口支持继承,继承用 extends
  • 类可以遵守多个接口,遵守用 implements
js 复制代码
// 定义接口
interface pro {
  name: string;
  eat(): void; // 协议里面,返回值类型必须写
}

// 接口支持继承
interface pro1 extends pro {
  age: number;
  run(): void;// 协议里面,返回值类型必须写
}

// 类可以遵守多个接口
class Person implements pro, pro1 {
  name: string = '';
  age: number = 0;
  eat() {
    console.log('吃呀,吃呀,吃一个啊~');
  }
  run() {
    console.log('run~~');
  }
}

2.1 接口 vs 抽象类

  • 类多继承接口,单继承抽象类
  • 接口不能有静态代码块及方法,抽象类可以
  • 接口不能有方法实现,抽象类可以(定义普通方法可以有时实现)
  • 接口不能有构造函数,抽象类可以

三 泛型类、接口及函数

3.1 泛型接口,泛型类

js 复制代码
// 泛型接口, 泛型Element继承p1,p2接口
interface pro <Element extends p1, p2> {
  num: Element;
}

class Person<Element> {

}

let p = new Person<string>();

3.2 泛型函数

js 复制代码
// 返回数组最后一个元素
function lastElement<E>(array: E[]): E {
  return array[array.length - 1];
}

let last = lastElement<number>([1,2,3]); // 3

四 空安全

4.1 T | null | undefined

  • arkts不允许直接赋值为 null 或 undefined
  • 想赋值为null / undefined,需要定义联合类型 T | null | undefined
js 复制代码
let x: number | null | undefined;
x = null;
x = undefined;

4.2 !非空断言预算符

  • 告诉编译器,这个值肯定不是 null/undefined,放心用,出了事我负责
js 复制代码
clss A {
  value: string = '';
}

function foo(a: A| null) {
   a!.value; // 如果真的a为nill,则程序崩溃
}

4.3 支持空合并运算符及可选链

  • 如果属性为null、undefined,则可选链返回undefined

五 模块

5.1 什么是模块

  • 一个.ets文件,就是一个模块
  • 还有.ts(TypeScript).js、.mjs、.cjs(JavaScript)``.jsx、.tsx (Rect)

5.2 静态导出

js 复制代码
// 导出类
export class Person {

}

// 导出对象p
export let p = new Person()

// 导出方法
export function sum(num1: number, num2: number): number {
  return num1 + num2;
}

5.3 静态导入

  • 导入路径:导入的模块

  • 导入绑定:把导出的所有东西打包放进包裹"A",用A.XXX拆开用

5.3.1 路径知识补充

js 复制代码
./ = 当前目录

../ = 上一级目录

../../ = 上两级目录

../../../ = 上三级目录
js 复制代码
entry/src/main/ets/
├── entryability/
│   └── EntryAbility.ets          ← 文件1
├── pages/
│   └── Index.ets                 ← 文件2

// 在Index.ets  中 引入 EntryAbility.ets 

../entryability/EntryAbility
js 复制代码
// utils.ets - 导出各种东西


// 导出类
export class Person {
  name: string = '';
  age: number = 0;
  
  constructor (name: string, age: number) {
    this.name = name;
    this.age = age;
  }
  
  sayHello(name: string) {
    console.log(`${this.name} say hello`)
  }

}

// 导出函数
export function add(a: number, b: number): number {
    return a + b;
}

// 导出常量
export const PI = 3.14159;

// 导出实例(现成的对象)
export let defPerson = new Person("默认用户", 18);
csharp 复制代码
// 目录结构

project/
├── utils.ets    # 导出模块
└── app.ets      # 导入并使用

5.3.2 导入路径(不带前缀使用)

js 复制代码
// app.ets 导入各种东西

import {Person, add, PI, defPerson} from ./utils;

let p = new Person();

add(1,2);

console.log(PI);

defPerson.sayHello('小华'); // 小华 say hello

5.3.3 全部导入(带前缀使用)

js 复制代码
// app.ets 导入各种东西

import * as Untils from ./utils;//"Untils"为别名,可自定义,通过该名称调用模块的接口。

let p = new Untils.Person();

Untils.add(1,2);

console.log(Untils.PI);

Untils.defPerson.sayHello('小华'); // 小华 say hello

5.4 导入,导出(动态)'

  • import('./Feature') 返回Promise对象
js 复制代码
// ========== Feature.ts ==========

//1 单独导出变量和函数
export const FEATURE_VERSION = '2.1.0';

export function doSomething(): void {
    console.log('执行了 doSomething');
}

export function calculate(a: number, b: number): number {
    return a + b;
}

// 2 导出类
export class FeatureService {
    private name: string;

    constructor(name: string) {
        this.name = name;
    }

    greet(): string {
        return `Hello from ${this.name}`;
    }
}

// 3 集中导出(统一对外暴露)
const helper = (msg: string) => console.log('Helper:', msg);
const config:Record<string,number> = { 'maxRetry': 3, 'timeout':5000 };
export { helper, config };

export { helper, config };

// 4 默认导出(模块的"主角")
// 每个模块只能有一个 export default
export default class FeatureMain {
    run(): void {
        console.log('FeatureMain 运行中...');
    }
}

5.4.1 同步方法中,获取导入

js 复制代码
// ========== Main.ets ==========

import('./Feature')
    .then((module) => {
        // 通过 .default 获取 export default标记的类
        const MainClass = module.default;

        const instance = new MainClass();
        instance.run(); // 输出: FeatureMain 运行中...

        // ---------- 访问具名导出 ----------
        console.log(module.FEATURE_VERSION); // 输出: 2.1.0

        module.doSomething(); // 输出: 执行了 doSomething

        const result = module.calculate(10, 20);
        console.log('计算结果:', result); // 输出: 30

        // ---------- 使用导出类 ----------
        const service = new module.FeatureService('ArkTS');
        console.log(service.greet()); // 输出: Hello from ArkTS

        // ---------- 使用集中导出的内容 ----------
        module.helper('动态导入成功!'); // 输出: Helper: 动态导入成功!
        console.log(module.config.maxRetry); // 输出: 3
    })
    .catch((err: Error) => {
        console.error('模块加载失败:', err.message);
    });

// 

5.4.2 异步方法中,获取导入

js 复制代码
async function test() {
  let ns = await import('./say');// 等待 promise 对象完成
  let hi = ns.hi;
  let bye = ns.bye;
  hi();
  bye();
}

// 不加 await
// 输出: Promise { <pending> }  ← 只是一个 Promise 对象,不是真正的值

// 添加 await
// 输出: { hi: [Function], bye: [Function] }  ← 真正的模块对象

5.5 引入SDK

js 复制代码
// 引入系统的UIKit,引入华为UI组件
import UIAbility from '@ohos.app.ability.UIAbility'; 
js 复制代码
// 导入单接口
import { UIAbility } from '@kit.AbilityKit';
js 复制代码
//导入多接口
import { UIAbility, Ability, Context } from '@kit.AbilityKit';
js 复制代码
// "module"为别名,可自定义,然后通过该名称调用模块的接口。
import * as module from '@kit.AbilityKit';

六 注解

  • 定义注解,通过框架,获取注解信息,实现代码封装
js 复制代码
@interface API {
  path: string;
  method: string;
}

@API({path: 'http://123@.com',method: 'Get'})
clsss loadData {

}
相关推荐
TrisighT6 小时前
ArkTS 的 @BuilderParam 你八成只用了皮毛——那个尾随闭包写法差点被我当 bug 删了
harmonyos·arkts·arkui
TrisighT1 天前
ArkTS 列表滚动时为什么会闪现旧数据?我扒了 LazyForEach 的复用逻辑
harmonyos·arkts·arkui
TrisighT2 天前
一个下午搞定 ArkTS 折叠面板?结果我从两点写到晚上九点
harmonyos·arkts·arkui
TrisighT9 天前
AI写埋点代码,35%覆盖率坑惨运营
harmonyos·arkts·arkui
TrisighT13 天前
AI写鸿蒙UI:10个跑崩8个,剩下2个看运气
ai编程·harmonyos·arkts
至乐活着13 天前
HarmonyOS开发深度解析:网络请求与数据持久化实战全攻略
网络请求·harmonyos·arkts·数据持久化·鸿蒙开发
ZJPRENO15 天前
2026华为HDC AI 编程核心成果总结
华为·arkts
全栈若城17 天前
HarmonyOS ArkWeb 系列之文本选中菜单定制:editMenuOptions 深度解析
arkts·arkweb·harmonyos6·editmenuoptions·textmenuitem
TrisighT17 天前
ArkTS 组件传对象还是拆属性?我测了帧率,结果和直觉反着来
harmonyos·arkts