首页 > 其他分享 ># TypeScript 中的类使用

# TypeScript 中的类使用

时间:2023-12-26 16:23:24浏览次数:28  
标签:TypeScript console name age class 使用 public string

TypeScript 中的类使用

学习资料:https://ts.xcatliu.com/advanced/class.html

传统方法中,JavaScript 通过构造函数实现类的概念,通过原型链实现继承。而在 ES6 中,我们终于迎来了 class

TypeScript 除了实现了所有 ES6 中的类的功能以外,还添加了一些新的用法。

类的概念

虽然 JavaScript 中有类的概念,但是可能大多数 JavaScript 程序员并不是非常熟悉类,这里对类相关的概念做一个简单的介绍。

  • 类(Class):定义了一件事物的抽象特点,包含它的属性和方法 对象(Object):类的实例,通过 new 生成。
  • 面向对象(OOP)的三大特性:封装、继承、多态。
  • 封装(Encapsulation):将对数据的操作细节隐藏起来,只暴露对外的接口。外界调用端不需要(也不可能)知道细节,就能通过对外提供的接口来访问该对象,同时也保证了外界无法任意更改对象内部的数据。
  • 继承(Inheritance):子类继承父类,子类除了拥有父类的所有特性外,还有一些更具体的特性。
  • 多态(Polymorphism):由继承而产生了相关的不同的类,对同一个方法可以有不同的响应。比如 CatDog 都继承自
    Animal,但是分别实现了自己的 eat 方法。此时针对某一个实例,我们无需了解它是 Cat 还是 Dog,就可以直接调用 eat
    方法,程序会自动判断出来应该如何执行 eat
  • 存取器(getter & setter):用以改变属性的读取和赋值行为。
  • 修饰符(Modifiers):修饰符是一些关键字,用于限定成员或类型的性质。比如 public 表示公有属性或方法。
  • 抽象类(Abstract Class):抽象类是供其他类继承的基类,抽象类不允许被实例化。抽象类中的抽象方法必须在子类中被实现。
  • 接口(Interfaces):不同类之间公有的属性或方法,可以抽象成一个接口。接口可以被类实现(implements)。一个类只能继承自另一个类,但是可以实现多个接口。

属性和方法

使用 class 定义类,使用 constructor 定义构造函数。

通过 new 生成新实例的时候,会自动调用构造函数。

// 类:描述了所创建的对象共同的属性和方法。
// 通过类可以实例化对象

class Person {
  name: string
  age: number
  // 构造器函数
  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }

  sayHi(str: string) {
    console.log(`hi :${str}`)
  }
}
let p = new Person('我是ed.', 25) // 在new的时候,会执行类中的构造方法。
p.sayHi("我是ed.")

类的继承

使用 extends 关键字实现继承,子类中使用 super 关键字来调用父类的构造函数和方法。

// 定义为父类
class Animal {
  name: string;
  age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
  sayHi(str: string) {
    console.log("hi " + str + "!")
  }
}

// 定义为子类
class Dog extends Animal {
  constructor(name: string, age: number) {
    // 调用父类的构造函数
    super(name, age);
  }
  sayHi(str: string) {
    console.log("dog " + str + "!")
  }
}

const cat = new Animal("小猫", 10);
cat.sayHi("小猫");

const dog = new Dog("小狗", 5);
dog.sayHi("我是一只小狗")

编译完成,查看运行结果:

在这里插入图片描述

注意,我们可以通过 super.sayHi("狗子") 直接调用父类的方法。

总结:

  • 类与类之间存在继承关系,通过 extends 进行继承。
  • 子类可以调用父类的方法,通过 super
  • 子类可以重写父类的方法。

存取器

使用 gettersetter 可以改变属性的赋值和读取行为:

// 使用 getter 和 setter 可以改变属性的赋值和读取行为
class Name {
    constructor(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
    // 设置存取器
    // 读取器 用来读取数据
    get fullName() {
        // 姓名 = 姓氏 + 名字
        return this.firstName + ' ' + this.lastName;
    }
    // 设置器 用来设置数据
    set fullName(name) {
        this.firstName = name;
    }
}
const n = new Name('我是', 'ed.');
console.log(n.fullName);
n.fullName = '我是谁';
console.log(n.fullName);

看一下打印的结果:

在这里插入图片描述

静态成员

静态成员包含静态属性和静态方法,只属于类自己的属性和方法。

使用 static 修饰符修饰的方法称为静态方法,它们不需要实例化,而是直接通过类来调用:

// 静态方法 + 静态属性

class A {
  static name1: string  // 静态属性
  static sayHi() {   // 静态方法
    console.log('hi')
  }
}
A.sayHi()  // 静态方法
const a1 = new A()
a1.sayHi() 

这时候发现,ts 编译器会报错:

在这里插入图片描述

修饰符

TypeScript 可以使用三种访问修饰符(Access Modifiers),分别是 publicprivateprotected

  • public 修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是 public 的
  • private 修饰的属性或方法是私有的,不能在声明它的类的外部访问
  • protected 修饰的属性或方法是受保护的,它和 private 类似,区别是它在子类中也是允许被访问的

public 公有

public 修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是 public 的。

// ** public ** 修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是 public 的
class B {
  public name: string   // 表示公有的属性
  public constructor(name: string) {
    this.name = name
  }
  public p() {   // 表示公有的方法
    console.log(this.name)
  }
}

其实对于 public 而言,写不写都一样,因为不写的话,默认就是 public

所以上面的代码和下面的性质是一模一样的:

class B {
  name: string 
  constructor(name: string) {
    this.name = name
  }
  p() {
    console.log(this.name)
  }
}

private 私有

private 修饰的属性或方法是私有的,不能在声明它的类的外部访问。

class B {
  private name: string 
  constructor(name: string) {
    this.name = name  // name 设置为私有的,只能在类内部访问
  }
  p() {
    console.log(this.name)
  }
}

const b1 = new B('我是ed.')
console.log(b1.name) // 报错
b1.p()

我们声明了私有属性,在外部不能访问,所以说 console.log(b1.name) 会报错,和 java 一样是吧?

![在这里插入图片描述](/i/ll/?i=direct/6438004db1264570ab6642965b41c371.png

那现在出现一个问题啊,就是我在类B里面写了一个私有属性,那么如果有一个类C,继承B的话,他可以访问吗?试一下:

class B {
  private name: string 
  constructor(name: string) {
    this.name = name  // name 设置为私有的,只能在类内部访问
  }
  p() {
    console.log(this.name)
  }
}

// const b1 = new B('我是ed.')
// console.log(b1.name) // 报错
// b1.p()


class C extends B{
  constructor(name: string) { 
    super(name)  // 继承父类的属性
  }
}

const c = new C('我是ed.')
console.log(c.name)  // 报错

我们可以看到,报错了:

在这里插入图片描述

所以:子类你可以继承私有属性和私有方法, 但是你不可以访问。

哪怕去类C里面的方法打印一下都不可以:

class C extends B{
  constructor(name: string) { 
    super(name)  // 继承父类的属性
  }
  p() {
    console.log(this.name) // 报错
  }
}

依旧是报错的:

在这里插入图片描述

protected 受保护

protected 修饰的属性或方法是受保护的,它和 private 类似,区别是它在子类中也是允许被访问的

上面我们看到了,private 修饰后,子类就算继承了也不可以访问,但是我们想子类可以访问但是外部依旧不能访问,这个时候就需要 protected 了。

class B {
  protected name: string
  constructor(name: string) {
    this.name = name  // name 设置为私有的,只能在类内部访问
  }
  p() {
    console.log(this.name)
  }
}

class C extends B {
  constructor(name: string) {
    super(name)  // 继承父类的属性
  }
  p() {
    console.log(this.name)  // 不报错
  }
}

const c = new C('我是ed.')
console.log(c.name)    // 报错

这个时候呢,子类可以访问但是外部依旧不能访问:

在这里插入图片描述

可以看到,在子类可以继承且访问,但是在外部是不可以访问的。

readonly

只读属性关键字,只允许出现在属性声明或索引签名或构造函数中。

class X {
  readonly age:number  // 表示该属性只读,但是在构造函数中是可以修改的
  constructor(age:number) {
    this.age = age
  }
  update() {
    this.age = 18  // 报错,不能够被修改,因为只读
  }
}

const x = new X(18)
console.log(x.age)
x.age = 20   // 报错,不允许被修改,因为只读

readonly 表示只读,除了在声明类的构造函数中允许修改外,其他位置均不可以修改:

在这里插入图片描述

如果我们的三个 修饰符 和 readonly 定义在参数上面,那么他会创建并且初始化参数

// readonly

class X {
  readonly age:number  // 表示该属性只读,但是在构造函数中是可以修改的
  constructor(readonly age:number) {
    this.age = age
  }
  update() {
    this.age = 18  // 报错,不能够被修改,因为只读
  }
}

const x = new X(18)
console.log(x.age)
x.age = 20   // 报错,不允许被修改,因为只读

看,报错了!

抽象类 abstract

abstract 用于定义抽象类和其中的抽象方法。

什么是抽象类?

首先,抽象类是不允许被实例化的:

// 抽象类
abstract class A {
  public name;
  public constructor(name) {
    this.name = name;
  }
  public abstract sayHi();
}

let a = new A('Jack');

看,直接实例化一个抽象类,直接报错,告诉我们不允许:

在这里插入图片描述
上面的例子中,我们定义了一个抽象类 Animal,并且定义了一个抽象方法 sayHi。在实例化抽象类的时候报错了。

其次,抽象类中的抽象方法必须被子类实现:

// 抽象类
abstract class A {
  public name;
  public constructor(name) {
    this.name = name;
  }
  public abstract sayHi();
}

class C extends A {
  public eat() {
    console.log(`${this.name} is eating.`);
  }
}

let c = new C('Tom');

上面的例子中,我们定义了一个类 Cat 继承了抽象类 Animal,但是没有实现抽象方法 sayHi,所以编译报错了。

在这里插入图片描述

下面是一个正确使用抽象类的例子:

abstract class Animal {
  public name;
  public constructor(name) {
    this.name = name;
  }
  public abstract sayHi();
}

class Cat extends Animal {
  public sayHi() {
    console.log(`Meow, My name is ${this.name}`);
  }
}

let cat = new Cat('Tom');

上面的例子中,我们实现了抽象方法 sayHi,编译通过了。

标签:TypeScript,console,name,age,class,使用,public,string
From: https://www.cnblogs.com/wjw1014/p/17928389.html

相关文章

  • Charles 功能介绍和使用教程
    Charles功能介绍和使用教程Android爱好者2018-08-27146,318阅读24分钟   Charles简介Charles是在PC端常用的网络封包截取工具,在做移动开发时,我们为了调试与服务器端的网络通讯协议,常常需要截取网络封包来分析。除了在做移动开发中调试端口外,Charles也可以用......
  • NET开发中合理使用对象映射库,简化和提高工作效率
    NET开发中合理使用对象映射库,简化和提高工作效率 思维导航前言使用对象映射库有哪些好处?AutoMapper对象映射库介绍创建一个控制台应用AutoMapper包安装创建源对象和目标对象配置AutoMapper映射规则控制台执行对象映射项目源码地址优秀项目和框架精选DotNetGuide......
  • Centos7使用Docker部署Nextcloud
    基础环境系统centos7.9内存2G以上磁盘30G以上安装部署1、安装基础工具[root@localhost~]#yum-yinstallvimnet-toolsnmaptreelrzszlsof2、添加阿里docker源[root@localhost~]#wget-P/etc/yum.repos.d/https://mirrors.aliyun.com/docker-ce/linux/centos/docker-......
  • 查看onnx模型结构-使用Netron模块
    查看onnx模型结构-使用Netron模块1安装$pipinstallnetron2可选-查看安装的路径$pipshownetron3查看onnx结构importnetron#�??�?ONNX模�??�??件�??路�?onnx_model_path=r'yolo5/yolov5n-seg_toXiaoLiu/model/yolov5n-seg.onnx'#�?�"�netron�?��?��?�??ONNX模�??net......
  • 使用 Jamf Protect 阻止潜在的隔空投送传输数据泄露
    JamfProtect可以集中统一日志数据,以便进行过滤和更好的搜索。一个用例是检测出站隔空投送传输并记录它们,以防止可能的数据泄露。通过统一日志记录改进基于文本的日志基于文本的日志长期以来一直是IT和安全团队寻求深入了解Mac和Unix系统的主要内容。然而,这些日志通常很大,数......
  • 如何使用ChatGPT快速构建一个网站模板
    圣诞狂欢,感恩有你......
  • [转]TypeScript编写类继承函数相关的代码
    TypeScript编写类,继承、函数相关的代码classPerson{privatename:stringprivateage:Numberconstructor(name:string,age:Number){this.name=name;this.age=age}publicgetPersonInfo():string{return`Myname......
  • JMeter使用入门
    Jmeter下载地址ApacheJMeter-DownloadApacheJMeter使用教程解压jmeter,打开bin里面的jmeter.bat,输入testplan的名字在plan右键,选中ThreadGroup新建线程group后在ThreadGroup右键添加HTTPRequestDefaults输入需要测的网址的http协议以及地址,端口号,输入后,新建其他H......
  • Linux使用PM2守护进程
    PM2:Node.js应用的进程管理工具Node.js是一个强大的服务器端JavaScript运行时,而在实际部署和管理Node.js应用时,需要一种有效的进程管理工具。PM2(ProcessManager2)正是为此而生,它提供了一套全面的功能,使得在生产环境中轻松管理Node.js进程成为可能。安装PM2首先,确保......
  • # TypeScript 枚举 enum
    TypeScript枚举enum学习资料:https://ts.xcatliu.com/advanced/enum.html枚举(Enum)类型用于取值被限定在一定范围内的场景,比如一周只能有七天,颜色限定为红绿蓝等。枚举赋值简单理解就是给一组数值赋予名称。//枚举对象enumNumberType{one=1,two,three,fo......