Skip to content

类与接口

上次更新 2024年10月9日星期三 1:45:28 字数 1660 字 时长 7 分钟

类的定义

下面是使用 TS 约束属性并实例化对象

ts
class User {
  name: string;
  age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
  info(): string {
    return `${this.name}的年龄是${this.age}`;
  }
}

const A = new User('张三',12);
const B = new User('李四'18);

通过数组类型为 User,使其成员只能是 User 类型对象

ts
const users: User[] = [A, B];

修饰符

下面我们来掌握 JS 类与 TS 结合使用

public

下面我们介绍第一个访问修饰符,public,指公开的属性或方法

  • 默认情况下属性是 public,即可以在类的内外部进行修改访问。
  • 不明确设置为 public,默认就是 public。
ts
class User {
  public name: string;
  public age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
  public info(): string {
    return `${this.name}的年龄是${this.age}`;
  }
}

protected

protected 修饰符指的受保护的,只允许在父类与子类使用,不允许在类的外部使用。

ts
class User {
  protected name: string;
  protected age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
  protected info(): string {
    return `${this.name}的年龄是${this.age}`;
  }
}

// 子类访问 protected 属性
class Admin extends User {
  constructor(name: string, age: number) {
    super(name, age);
  }
  public info(): string {
    return `${this.name}的年龄是${this.age}`;
  }
}
const A = new User("张三", 12);
A.name = "李四"; // error

private

private 修饰符值私有的,不允许在子类与类外部使用。 父类声明 private 属性或属性,子类无法访问。

子类更改父类方法或属性的访问修饰符限制。 父类 public 子类只能是 public 父类是 protected 子类可以是 protected 或 public 父类是 private 子类不能访问修改

readonly

readonly 修饰符指的只读的,不允许在类的内部与外部进行修改。

  • 类似于 const 关键字
ts
class User {
  readonly name: string;
  constructor(name?: string) {
    this.name = name || this.name;
  }
}

constructor

构造函数是初始化实例参数使用的,在 TS 中有些细节与其他程序不同 我们可以在构造函数 constructor 中定义属性,这样就不用在类中声明属性了,可以简化代码量

ts
class User {
  constructor(public name: string, public age: number) {}
  info() {
    return `${this.name}的年龄是${this.age}`;
  }
}

static

static 用于定义静态属性或方法,属于或方法是属于构造函数的

  • 静态属性是属于构造函数的,不是对象独有的,所以是所有对象共享的
  • 属于类本身 可以直接通过类名直接访问

语法介绍

下面是 static 的使用语法

ts
class User {
  static name: string = "张三";
  static age: number = 12;
  static info() {
    return `${User.name}的年龄是${User.age}`;
  }
}

单例模式

当把 constructor 定义为非 public 时候,对象无法实例化。 结合 static,可以做到单例模式。

ts
class User {
  static instance: User;
  protected constructor() {}
  public static getInstance() {
    return User.instance || (User.instance = new User());
  }
}
let a = User.getInstance();

get/set

使用 get 与 set 访问器可以动态设置和获取属性

ts
class User {
  private _name;
  constructor(name: string) {
    this._name = name;
  }
  public get name() {
    return this._name;
  }
  public set name(value) {
    this._name = value;
  }
}

const a = new User("张三");
a.name = "李四";
console.log(a.name);

abstract

抽象类定义使用 abstract 关键字,抽象类除了具有普通类功能外,还可以定义抽象方法。

  • 抽象类不能被实例化,只能被继承。
  • 父级声明 子级实现抽象方法。
  • 抽象法方法只能定义不能实现,即没有函数体。
ts
abstract class User {
  abstract info(): string;
  constructor(public name: string, public age: number) {
    this.name = name;
    this.age = age;
  }
}
class Admin extends User {
  constructor() {}
  info(): string {
    return `${this.name}的年龄是${this.age}`;
  }
}

interface

接口用于描述类和对象的结构

  • 使项目中不同文件使用的对象保持统一的规范
  • 使用接口 ,提供规范的代码提示

抽象类

下面是抽象类与接口的结合使用 ???

ts
interface UserInterface {
  name: string;
  info(): string;
}
abstract class User implements UserInterface {
  info(): string;
}
class Admin extends User {
  constructor(name: string) {
    super(name);
  }
  info(): string {
    return `${this.name}`;
  }
}

对象

下面使用接口来约束对象

ts
interface UserInterface {
  name: string;
  age: number;
  isLock: boolean;
  info(other: string): string;
}

const admin: UserInterface = {
  name: "change",
  age: 18,
  isLock: false,
  info(o: string) {
    return `${this.name}已经${this.age}岁了,${o}`;
  },
};

console.log(admin.info());

如果尝试不存在的函数或属性时,会报错 如果有额外的属性,可以使用以下方式声明接口,可以是任意的属性

ts
interface UserInterface {
  name: string;
  age: number;
  [key: string]: any;
}

接口的继承

接口可以通过extends关键字继承接口

ts
interface interface1 {
  name: string;
}
interface interface2 extends interface1 {
  age: number;
}

对象可以使用多个接口,多个接口用逗号隔开

ts
interface interface1 {
  name: string;
  info(): string;
}
interface interface2 {
  age: number;
  getAge(): number;
}
class User implements interface1, interface2 {
  name: string;
  age: number;
  getAge(): number {
    return this.age;
  }
  info(): string {
    return `${this.name}的年龄是${this.age}`;
  }
}

函数

下面是函数与接口结合使用

ts
interface UserInterface {
  name: string;
  age: number;
}
function getInfo(user: UserInterface): UserInterface {
  return user;
}

构造函数

与构造函数的结合

ts
interface UserInterface {
  name: string;
  age: number;
}
class User {
  constructor(user: UserInterface) {
    this.name = user.name;
    this.age = user.age;
  }
}

数组

对数组类型使用接口进行约束

ts
interface UserInterface {
  name: string;
  age: number;
}
const admin1: UserInterface = {
  name: "name1",
  age: 12,
};
const admin2: UserInterface = {
  name: "name2",
  age: 12,
};
const admins: UserInterface[] = [admin1, admin2];

枚举

下面是使用枚举设置性别

ts
enum Sex {
    BOY:'男',
    GRID:'女'
}
interface UserInterface {
    name:string,
    sex:SexType
}

const admin:UserInterface = {
    name:'name',
    sex:Sex.BOY
}

type

type 与 interface 非常相似都可以描述一个对象或函数,使用 type 用于定义类型的别名,是非常灵活的类型定义方式。

  • type 可以定义基本类型别名,如联合类型、元组
  • type 与 interface 都可以进行扩展
  • 使用 type 比 interface 更灵活
  • 如果熟悉其他编程语言,interface 会让你更亲切
  • 使用类(class)是建议使用 interface,这可以与其他编程语言保持统一。
  • 决定使用哪个声明方式,最终考量公司团队(个人)的规范。

基本使用

下面是使用的 type 声明对象类型

ts
type User = {
  name: string;
  age: number;
};

type 声明函数的方式

ts
type User = (name: string, age: number) => string;
const getInfo: User = (name: string, age: number) => {
  return `${name}的年龄是${age}`;
};

类型别名

type 可以为 number、string、boolean、object、array、function 等类型

ts
// 基本类型
type Name = string;
// 联合类型定义
type Age = number | string;
type User = {
  isAdmin: boolean;
  age: Age;
};
const a: User = {
  isAdmin: true,
  age: 12,
};
// 元组
const users: [User] = [a];

索引类型

type 与 interface 在索引类型上声明是相同的

ts
type User1 = {
  name: string;
  age: number;
  [key: string]: any;
};
interface User2 {
  name: string;
  age: number;
  [key: string]: any;
}

声明继承

interface 会将同名的声明进行合并 合并方式

  • &
  • extends
ts
type User1 = {
  name: string;
};
type User2 = User1 & { age: number };

interface User3 {}
interface User4 {}
type u5 = User3 & User4;
interface User5 extends User3, User4 {}

implements

class 可以使用 implements 来实现 type 或 interface

ts
type UserType = {
  name: string;
};
class User implements UserType {
  name: string = "admin";
}
关注公众号