当前位置:   article > 正文

鸿蒙开发入门day05-ArkTs语言(接口与关键字)

鸿蒙开发入门day05-ArkTs语言(接口与关键字)

(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,还请三连支持一波哇ヾ(@^∇^@)ノ)

目录

ArkTS语言介绍  

接口

接口属性

接口继承

泛型类型和函数

泛型类和接口

泛型约束

泛型函数

泛型默认值

模块

导出

导入

静态导入

动态导入

导入HarmonyOS SDK的开放能力

顶层语句

程序入口

关键字

this


ArkTS语言介绍  

接口

接口声明引入新类型。接口是定义代码协定的常见方式。

任何一个类的实例只要实现了特定接口,就可以通过该接口实现多态。

接口通常包含属性和方法的声明

示例:

  1. interface Style {
  2. color: string // 属性
  3. }
  4. interface AreaSize {
  5. calculateAreaSize(): number // 方法的声明
  6. someMethod(): void; // 方法的声明
  7. }

实现接口的类示例:

  1. // 接口:
  2. interface AreaSize {
  3. calculateAreaSize(): number // 方法的声明
  4. someMethod(): void; // 方法的声明
  5. }
  6. // 实现:
  7. class RectangleSize implements AreaSize {
  8. private width: number = 0
  9. private height: number = 0
  10. someMethod(): void {
  11. console.log('someMethod called');
  12. }
  13. calculateAreaSize(): number {
  14. this.someMethod(); // 调用另一个方法并返回结果
  15. return this.width * this.height;
  16. }
  17. }

接口属性

接口属性可以是字段、getter、setter或getter和setter组合的形式。

属性字段只是getter/setter对的便捷写法。以下表达方式是等价的:

  1. interface Style {
  2. color: string
  3. }
  1. interface Style {
  2. get color(): string
  3. set color(x: string)
  4. }

实现接口的类也可以使用以下两种方式:

  1. interface Style {
  2. color: string
  3. }
  4. class StyledRectangle implements Style {
  5. color: string = ''
  6. }
  1. interface Style {
  2. color: string
  3. }
  4. class StyledRectangle implements Style {
  5. private _color: string = ''
  6. get color(): string { return this._color; }
  7. set color(x: string) { this._color = x; }
  8. }

接口继承

接口可以继承其他接口,如下面的示例所示:

  1. interface Style {
  2. color: string
  3. }
  4. interface ExtendedStyle extends Style {
  5. width: number
  6. }

继承接口包含被继承接口的所有属性和方法,还可以添加自己的属性和方法。

泛型类型和函数

泛型类型和函数允许创建的代码在各种类型上运行,而不仅支持单一类型。

泛型类和接口

类和接口可以定义为泛型,将参数添加到类型定义中,如以下示例中的类型参数Element:

  1. class CustomStack<Element> {
  2. public push(e: Element):void {
  3. // ...
  4. }
  5. }

要使用类型CustomStack,必须为每个类型参数指定类型实参:

  1. let s = new CustomStack<string>();
  2. s.push('hello');

 编译器在使用泛型类型和函数时会确保类型安全。参见以下示例:

  1. let s = new CustomStack<string>();
  2. s.push(55); // 将会产生编译时错误

泛型约束

泛型类型的类型参数可以被限制只能取某些特定的值。例如,MyHashMap<Key, Value>这个类中的Key类型参数必须具有hash方法。

  1. interface Hashable {
  2. hash(): number
  3. }
  4. class MyHashMap<Key extends Hashable, Value> {
  5. public set(k: Key, v: Value) {
  6. let h = k.hash();
  7. // ...其他代码...
  8. }
  9. }

在上面的例子中,Key类型扩展了Hashable,Hashable接口的所有方法都可以为key调用。

泛型函数

使用泛型函数可编写更通用的代码。比如返回数组最后一个元素的函数:

  1. function last(x: number[]): number {
  2. return x[x.length - 1];
  3. }
  4. last([1, 2, 3]); // 3

如果需要为任何数组定义相同的函数,使用类型参数将该函数定义为泛型:

  1. function last<T>(x: T[]): T {
  2. return x[x.length - 1];
  3. }

现在,该函数可以与任何数组一起使用。

在函数调用中,类型实参可以显式或隐式设置:

  1. // 显式设置的类型实参
  2. last<string>(['aa', 'bb']);
  3. last<number>([1, 2, 3]);
  4. // 隐式设置的类型实参
  5. // 编译器根据调用参数的类型来确定类型实参
  6. last([1, 2, 3]);

泛型默认值

泛型类型的类型参数可以设置默认值。这样可以不指定实际的类型实参,而只使用泛型类型名称。下面的示例展示了类和函数的这一点。

  1. class SomeType {}
  2. interface Interface <T1 = SomeType> { }
  3. class Base <T2 = SomeType> { }
  4. class Derived1 extends Base implements Interface { }
  5. // Derived1在语义上等价于Derived2
  6. class Derived2 extends Base<SomeType> implements Interface<SomeType> { }
  7. function foo<T = number>(): T {
  8. // ...
  9. }
  10. foo();
  11. // 此函数在语义上等价于下面的调用
  12. foo<number>();

模块

程序可划分为多组编译单元或模块。

每个模块都有其自己的作用域,即,在模块中创建的任何声明(变量、函数、类等)在该模块之外都不可见,除非它们被显式导出。

与此相对,从另一个模块导出的变量、函数、类、接口等必须首先导入到模块中。

导出

可以使用关键字export导出顶层的声明。

未导出的声明名称被视为私有名称,只能在声明该名称的模块中使用。

注意:通过export方式导出,在导入时要加{}。

  1. export class Point {
  2. x: number = 0
  3. y: number = 0
  4. constructor(x: number, y: number) {
  5. this.x = x;
  6. this.y = y;
  7. }
  8. }
  9. export let Origin = new Point(0, 0);
  10. export function Distance(p1: Point, p2: Point): number {
  11. return Math.sqrt((p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y));
  12. }

导入

静态导入

导入声明用于导入从其他模块导出的实体,并在当前模块中提供其绑定。导入声明由两部分组成:

  • 导入路径,用于指定导入的模块;
  • 导入绑定,用于定义导入的模块中的可用实体集和使用形式(限定或不限定使用)。

导入绑定可以有几种形式。

假设模块具有路径“./utils”和导出实体“X”和“Y”。

导入绑定* as A表示绑定名称“A”,通过A.name可访问从导入路径指定的模块导出的所有实体:

  1. import * as Utils from './utils'
  2. Utils.X // 表示来自Utils的X
  3. Utils.Y // 表示来自Utils的Y

导入绑定{ ident1, ..., identN }表示将导出的实体与指定名称绑定,该名称可以用作简单名称:

  1. import { X, Y } from './utils'
  2. X // 表示来自utils的X
  3. Y // 表示来自utils的Y

如果标识符列表定义了ident as alias,则实体ident将绑定在名称alias下:

  1. import { X as Z, Y } from './utils'
  2. Z // 表示来自Utils的X
  3. Y // 表示来自Utils的Y
  4. X // 编译时错误:'X'不可见
动态导入

应用开发的有些场景中,如果希望根据条件导入模块或者按需导入模块,可以使用动态导入代替静态导入。

import()语法通常称为动态导入dynamic import,是一种类似函数的表达式,用来动态导入模块。以这种方式调用,将返回一个promise。

如下例所示,import(modulePath)可以加载模块并返回一个promise,该promise resolve为一个包含其所有导出的模块对象。该表达式可以在代码中的任意位置调用。

  1. let modulePath = prompt("Which module to load?");
  2. import(modulePath)
  3. .then(obj => <module object>)
  4. .catch(err => <loading error, e.g. if no such module>)

如果在异步函数中,可以使用let module = await import(modulePath)。

  1. // say.ts
  2. export function hi() {
  3. console.log('Hello');
  4. }
  5. export function bye() {
  6. console.log('Bye');
  7. }

那么,可以像下面这样进行动态导入:

  1. async function test() {
  2. let ns = await import('./say');
  3. let hi = ns.hi;
  4. let bye = ns.bye;
  5. hi();
  6. bye();
  7. }

更多的使用动态import的业务场景和使用实例见动态import

导入HarmonyOS SDK的开放能力

HarmonyOS SDK提供的开放能力(接口)也需要在导入声明后使用。可直接导入接口模块来使用该模块内的所有接口能力,例如:

import UIAbility from '@ohos.app.ability.UIAbility';

从HarmonyOS NEXT Developer Preview 1版本开始引入Kit概念。SDK对同一个Kit下的接口模块进行了封装,开发者在示例代码中可通过导入Kit的方式来使用Kit所包含的接口能力。其中,Kit封装的接口模块可查看SDK目录下Kit子目录中各Kit的定义。

通过导入Kit方式使用开放能力有三种方式:

方式一:导入Kit下单个模块的接口能力。例如:

import { UIAbility } from '@kit.AbilityKit';

方式二:导入Kit下多个模块的接口能力。例如:

import { UIAbility, Ability, Context } from '@kit.AbilityKit';

方式三:导入Kit包含的所有模块的接口能力。例如:

import * as module from '@kit.AbilityKit';

其中,“module”为别名,可自定义,然后通过该名称调用模块的接口。

顶层语句

模块可以包含除return语句外的任何模块级语句。

如果模块包含主函数(程序入口),则模块的顶层语句将在此函数函数体之前执行。否则,这些语句将在执行模块的其他功能之前执行。

程序入口

程序(应用)的入口是顶层主函数。主函数应具有空参数列表或只有string[]类型的参数。

  1. function main() {
  2. console.log('this is the program entry');
  3. }

关键字

this

关键字this只能在类的实例方法中使用。

  1. class A {
  2. count: string = 'a'
  3. m(i: string): void {
  4. this.count = i;
  5. }
  6. }

使用限制:

  • 不支持this类型
  • 不支持在函数和类的静态方法中使用this

示例

  1. class A {
  2. n: number = 0
  3. f1(arg1: this) {} // 编译时错误,不支持this类型
  4. static f2(arg1: number) {
  5. this.n = arg1; // 编译时错误,不支持在类的静态方法中使用this
  6. }
  7. }
  8. function foo(arg1: number) {
  9. this.n = i; // 编译时错误,不支持在函数中使用this
  10. }

关键字this的指向:

  • 调用实例方法的对象
  • 正在构造的对象
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/990616
推荐阅读
  

闽ICP备14008679号