ArkTS基础语法--接口

2024-05-05 20:59:41 浏览数 (1)

接口

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

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

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

示例:

代码语言:javascript复制
interface Style {  color: string // 属性}interface AreaSize {  calculateAreaSize(): number // 方法的声明  someMethod(): void;     // 方法的声明}

实现接口的类示例:

代码语言:javascript复制
// 接口:interface AreaSize {  calculateAreaSize(): number // 方法的声明  someMethod(): void;     // 方法的声明}
// 实现:class RectangleSize implements AreaSize {  private width: number = 0  private height: number = 0  someMethod(): void {    console.log('someMethod called');  }  calculateAreaSize(): number {    this.someMethod(); // 调用另一个方法并返回结果    return this.width * this.height;  }}

接口属性

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

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

代码语言:javascript复制
interface Style {  color: string}
代码语言:javascript复制
interface Style {  get color(): string  set color(x: string)}

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

代码语言:javascript复制
interface Style {  color: string}
class StyledRectangle implements Style {  color: string = ''}
代码语言:javascript复制
interface Style {  color: string}
class StyledRectangle implements Style {  private _color: string = ''  get color(): string { return this._color; }  set color(x: string) { this._color = x; }}

接口继承

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

代码语言:javascript复制
interface Style {  color: string}
interface ExtendedStyle extends Style {  width: number}

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

泛型类型和函数

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

泛型类和接口

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

代码语言:javascript复制
class CustomStack<Element> {  public push(e: Element):void {    // ...  }}

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

代码语言:javascript复制
let s = new CustomStack<string>();s.push('hello');

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

代码语言:javascript复制
let s = new CustomStack<string>();s.push(55); // 将会产生编译时错误

泛型约束

泛型类型的类型参数可以绑定。例如,HashMap<Key, Value>容器中的Key类型参数必须具有哈希方法,即它应该是可哈希的。

代码语言:javascript复制
interface Hashable {  hash(): number}class HasMap<Key extends Hashable, Value> {  public set(k: Key, v: Value) {    let h = k.hash();    // ...其他代码...  }}

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

泛型函数

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

代码语言:javascript复制
function last(x: number[]): number {  return x[x.length - 1];}last([1, 2, 3]); // 3

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

代码语言:javascript复制
function last<T>(x: T[]): T {  return x[x.length - 1];}

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

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

代码语言:javascript复制
// 显式设置的类型实参last<string>(['aa', 'bb']);last<number>([1, 2, 3]);
// 隐式设置的类型实参// 编译器根据调用参数的类型来确定类型实参last([1, 2, 3]);

泛型默认值

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

代码语言:javascript复制
class SomeType {}interface Interface <T1 = SomeType> { }class Base <T2 = SomeType> { }class Derived1 extends Base implements Interface { }// Derived1在语义上等价于Derived2class Derived2 extends Base<SomeType> implements Interface<SomeType> { }
function foo<T = number>(): T {  // ...}foo();// 此函数在语义上等价于下面的调用foo<number>();

空安全

默认情况下,ArkTS中的所有类型都是不可为空的,因此类型的值不能为空。这类似于TypeScript的严格空值检查模式(strictNullChecks),但规则更严格。

在下面的示例中,所有行都会导致编译时错误:

代码语言:javascript复制
let x: number = null;    // 编译时错误let y: string = null;    // 编译时错误let z: number[] = null;  // 编译时错误

可以为空值的变量定义为联合类型T | null。

代码语言:javascript复制
let x: number | null = null;x = 1;    // okx = null; // okif (x != null) { /* do something */ }

非空断言运算符

后缀运算符!可用于断言其操作数为非空。

应用于空值时,运算符将抛出错误。否则,值的类型将从T | null更改为T:

代码语言:javascript复制
class C {  value: number | null = 1;}
let c = new C();let y: number;y = c.value   1;  // 编译时错误:无法对可空值作做加法y = c.value!   1; // ok,值为2

空值合并运算符

空值合并二元运算符??用于检查左侧表达式的求值是否等于null或者undefined。如果是,则表达式的结果为右侧表达式;否则,结果为左侧表达式。

换句话说,a ?? b等价于三元运算符(a != null && a != undefined) ? a : b。

在以下示例中,getNick方法如果设置了昵称,则返回昵称;否则,返回空字符串:

代码语言:javascript复制
class Person {  // ...  nick: string | null = null  getNick(): string {    return this.nick ?? '';  }}

可选链

在访问对象属性时,如果该属性是undefined或者null,可选链运算符会返回undefined。

代码语言:javascript复制
class Person {  nick: string | null = null  spouse?: Person
  setSpouse(spouse: Person): void {    this.spouse = spouse;  }
  getSpouseNick(): string | null | undefined {    return this.spouse?.nick;  }
  constructor(nick: string) {    this.nick = nick;    this.spouse = undefined;  }}

说明:getSpouseNick的返回类型必须为string | null | undefined,因为该方法可能返回null或者undefined。

可选链可以任意长,可以包含任意数量的?.运算符。

在以下示例中,如果一个Person的实例有不为空的spouse属性,且spouse有不为空的nickname属性,则输出spouse.nick。否则,输出undefined:

代码语言:javascript复制
class Person {  nick: string | null = null  spouse?: Person
  constructor(nick: string) {    this.nick = nick;    this.spouse = undefined;  }}
let p: Person = new Person('Alice');p.spouse?.nick; // undefined

---

我正在参与2024腾讯技术创作特训营最新征文,快来和我瓜分大奖!

0 人点赞