【TypeScript】中定义与使用 Class 类的解读理解

news2024/9/24 19:17:03

在这里插入图片描述

目录

    • `类的概念`
    • `类的继承` :
    • `类的存取器`:
    • `类的静态方法与静态属性`:
    • `类的修饰符`:
    • 参数属性:
    • `抽象类`:
    • `类的类型`:
  • 总结:

类的概念

类是用于创建对象的模板。他们用代码封装数据以处理该数据。JavaScript 中的类建立在原型上,但也具有某些语法和语义未与 ES5 类相似语义共享。


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

关于ES6的 Class 类语法概念,在本章节不做过多阐述,感兴趣的的小伙伴 可以 点击这里,了解查看更多 ES6中有关Class的语法概念使用。

本章节还是主要给大家带来,在 TypeScript 中,如何去定义 Class 【类】,以及如何去使用 类身上的 属性及方法。

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

在原生 JavaScript

class Rectangle {
    constructor(height, width) {
        this.height = height;
        this.width = width;
    }
}
new Rectangle(1, 2)   //实例化,并传入参数

上面的是,在JS中,Class 类的常用定义方式。

而在TypeScript 中定义 Class 类:

class identity {
    name: string;   //TS 中需要对要接受的参数初始化
    age: number;
    constructor(name: string, age: number) {    //为要传入的参数指定类型。不指定类型,默认为Any 类型。
        this.name = name;
        this.age = age;
    }
    sayHi() {
        return `我叫 ${this.name},今年${this.age}`;
    }
}
let a = new identity('张三', 20);
console.log(a);    //Animal {name: '张三', age: 20}

console.log(a.sayHi());  //我叫 张三,今年20岁

类的继承

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

class identity {   //父类
    name: string;
    age: number;
    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }
    sayHi() {
        return `我叫 ${this.name},今年${this.age}`;
    }
}

//子类
class copy extends identity {   
    //由于我继承了 identity ,在 identity 身上已经存在了 name 和 age
    // 所以 在 copy 类里面就不用再定义 name 和 age了,继承后可以直接读取到,所继承类身上的属性方法。
    constructor(name: string, age: number) {
        super(name, age)              // super 继承
    }
}
let c = new copy("李四", 30) //实例化子类
console.log(c);  //copy {name: '李四', age: 30}

//可以调用父类身上的方法。
console.log(c.sayHi());   //我叫 李四,今年30岁

类的存取器

使用 getter 和 setter 可以改变属性的赋值和读取行为。

存取器的作用:可以用来更专注化的控制对,对象属性方法的读取和修改。

class identity {   //父类
    name: string;
    age: number;
    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }
    //设置读取器=》,用来读取数据
    get names() {
        return "getter" + `我叫 ${this.name},今年${this.age}`;
    }

    //设置存储器,用来修改数据
    set names(val: string) {
        console.log("这是set 传入进来的值", val);
    }
}

let a = new identity("张三", 18);
console.log(a.names);  //当我们访问读取器的时候会触发get,会直接得到返回的值 : getter张三18
a.names = "李四" //当我们为存储器赋值的时候,会触发 set 并且会把,赋值,当成参数,传递给 set。

使用 存储器的好处:对属性方法的读取和修改,更加的专业化,不同的存取器,负责不同的逻辑处理,这里的存取器,也相似于 Vue 中的 computed 计算属性。 以及 Object.defineProperty()的 get 和 set 方法 类似。


类的静态方法与静态属性

有时候,我们希望 类中所定义的属性或者方法,不想被实例化后的对象读取,不需要实例化,那么,我们就可以通过 static 关键字,来把 属性或方法定义为静态成员来实现。

class identity {
    static username: string = "asdasd";    //将 username  通过 static 设置为静态属性。并为其赋值。
    name: string
    age: number;
    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
        console.log(this.username);  //也会报错,类的内部也不能拿取 username
    }

    //将方法设置为 静态方法
    static bolkfn() {
        console.log("静态方法");
    }
}



let a = new identity("张三", 18);

console.log(identity.username);  // 类自身访问静态属性,不会报错

console.log(a.username);      //实例对象访问静态属性,会报错 :属性“username”在类型“identity”上不存在。


console.log(identity.bolkfn());  // 类自身访问静态方法,不会报错

console.log(a.bolkfn());      //实例对象访问静态方法,会报错 :属性“bolkfn”在类型“identity”上不存在。

扩展知识点

在ES7 中有一些关于类的新特性提案,TypeScript 也实现了它们,这里做一个简单的介绍。

ES6 中实例的属性只能通过构造函数中的 this.xxx 来定义,而在 ES7 提案中可以直接在类里面定义:

class Animal {
  name = 'Jack';  //可以直接在类中定义,非必须要在 constructor 通过 this.name 来定义。

  constructor() {
    // ...
  }
}

let a = new Animal();
console.log(a.name); // Jack 可以直接读取到name属性 

类的修饰符

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

  • public :修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是 public
  • private 修饰的属性或方法是私有的不能在声明它的类的外部访问,虽然 子类 可以通过 extends 继承它的私有属性,但是却无法读取
  • protected : 修饰的属性或方法是受保护的,它和 private 类似,区别是它在子类中也是允许被访问的,也依然无法在外部访问

例:
public

class Animal {
  public name;
  public constructor(name) {
    this.name = name;
  }
}
let a = new Animal('Jack');
console.log(a.name); // Jack
a.name = 'Tom';
console.log(a.name); // Tom

private

class Animal {
    private name;   //设置私有化
    public constructor(name) {
        this.name = name;
    }
}

let a = new Animal('Jack');
console.log(Animal.name);  //只能自身读取

console.log(a.name);  //报错
a.name = 'Tom';   //报错

即使通过子类继承,在子类继承中也不能访问读取

class Animal {
  private name;
  public constructor(name) {
    this.name = name;
  }
}
class Cat extends Animal {
  constructor(name) {
    super(name);
    console.log(this.name);   //报错,子类继承中也无法访问私有化数据
  }
}

当构造函数修饰为 private 时,该类 允许被继承或者实例化:

class Animal {
    public name;
    private constructor(name) {  //构造函数 private 私有化
      this.name = name;
    }
  }
  class Cat extends Animal {  //报错不能被继承
    constructor(name) {
      super(name);
    }
  }
  
  let a = new Animal('Jack');  //报错,不应该被实例化

protected

当使用 protected 修饰,则 允许 在子类中访问:

class Animal {
  private name;
  public constructor(name) {
    this.name = name;
  }
}
class Cat extends Animal {
  constructor(name) {
    super(name);
    console.log(this.name);   //不会报错,子类继承中可以访问
  }
}

当构造函数修饰为 protected 时,该类只允许被继承:

class Animal {
    public name;
    protected constructor(name: string) {
        this.name = name;
    }
}
class Cat extends Animal {
    constructor(name: string) {
        super(name);
    }
}

let a = new Animal('Jack');  //报错,因为  Animal 只允许被继承。

参数属性:

上面,介绍的三种 修饰符,其实还有一种简洁的写法,被称为 属性参数写法;修饰符还可以使用在构造函数参数中等同于类中定义该属性同时给该属性赋值,使代码更简洁。

class Animal {
    // public name;   //可以省略此处
    protected constructor(public name: string) {  //  private   protected  同理
        // this.name = name;   //可以省略此处
    }
}

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

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

let a = new Animal('Jack');
console.log(a.name); // Jack
a.name = 'Tom';    //会报错,因为属性为 只读的,不能修改。

注意;
注意如果 readonly 和其他访问修饰符同时存在的话,需要写在其后面。

class Animal {
  // public readonly name;
  public constructor(public readonly name) {
    // this.name = name;
  }
}

抽象类

概念:抽象类的概念是,专注于用来为子类服务的,抽象类是不允许被实例化的,只能通过被子类继承。
语法:abstract 关键字用于定义抽象类和其中的抽象方法

abstract class Animal {  // 通过 abstract  定义一个抽象类
  public name;
  public constructor(name) {
    this.name = name;
  }
  public abstract sayHi();    //并且在抽象类里面,还可以定义 抽象方法
}

let a = new Animal('Jack');  //会报错,抽象类不能被实例化

注意抽象类中的抽象方法或属性必须被子类实现,否则在子类继承抽象类后,实例化的时候会报错

abstract class Animal {  // 通过 abstract  定义一个抽象类
    public name;
    public constructor(name) {
        this.name = name;
    }
    public abstract sayHi() { };    //并且在抽象类里面,还可以定义 抽象方法
}


class B extends Animal {
    public sayHi() {   //抽象类中,所定义抽象方法,必须要在子类中实现。
        console.log("继承Animal");

    }
}
let isB = new B("")

类的类型:

给实例化的类,定义类型,简述而言,就是定义的 class 类,还可以被用来当做 一种类型,赋值给实例化的对象,用来校验类的数据完整性。

案例说明:

class Animal {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
  sayHi(): string {
    return `My name is ${this.name}`;
  }
}

// 把 Animal  当做一种类型,用来校验实例化对象 a 的规范性。
let a: Animal = new Animal('Jack');
console.log(a.sayHi()); // My name is Jack

总结:

本章节,主要给大家介绍了,在 TypeScript 中,如何去声明 class 类,以及对 class 类的主要运用解析。欢迎大家交流评论。


🚵‍♂️ 博主座右铭:向阳而生,我还在路上!
——————————————————————————————
🚴博主想说:将持续性为社区输出自己的资源,同时也见证自己的进步!
——————————————————————————————
🤼‍♂️ 如果都看到这了,博主希望留下你的足迹!【📂收藏!👍点赞!✍️评论!】
——————————————————————————————

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/839128.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Leaflet入门,地图平移跳转到指定位置和飞行到指定位置效果

前言 本章讲解如何Leaflet如何实现操作地图平移到指定位置或者飞行到指定位置效果。 vue如何使用Leaflet vue2如何使用:《Leaflet入门,如何使用vue2-leaflet实现vue2双向绑定式的使用Leaflet地图,以及初始化后拿到leaflet对象,方便调用leaflet的api》 vue3如何使用:《L…

区块链实验室(15) - 编译FISCO BCOS的过程监测

首次编译开源项目,一般需要下载很多依赖包,尤其是从github、sourceforge等下载依赖包时,速度很慢,编译进度似乎没有一点反应,似乎陷入死循环,似乎陷入一个没有结果的等待。本文提供一种监测方法&#xff0c…

Leetcode-每日一题【剑指 Offer 10- I. 斐波那契数列】

题目 写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N))。斐波那契数列的定义如下: F(0) 0, F(1) 1 F(N) F(N - 1) F(N - 2), 其中 N > 1. 斐波那契数列由 0 和 1 开…

本地pycharm远程连接服务器运行自己的项目

配置服务器 打开pycharm,找到 工具–>部署–>配置 进入配置页面,点击左上角的加号,选择SFTP 弹出输入框,输入你自定义的服务器名称 点击ssh配置后面的省略选项 进入服务器配置页面 连接成功点击应用,然…

迅为全国产龙芯3A5000电脑运行统信UOS、银河麒麟、loongnix系统

iTOP-3A5000开发板采用全国产龙芯3A5000处理器,基于龙芯自主指令系统 (LoongArch) 的LA464微结构,并进一步提升频率,降低功耗,优化性能。在与龙芯3A4000处理器保持引脚兼容的基础上,频率提升至2.5GHZ,功耗降…

Nodejs实现读写文件和文件流

在Nodejs中,文件操作是非常常见的任务之一。它允许我们读取和写入文件,以及处理大型文件而不会消耗太多内存。本篇博文将会首先介绍一下文件和文件流的区别,然后全面介绍如何在Nodejs中实现文件操作和读写,包括使用文件系统模块&a…

echarts 图例组件legend配置

legend 图例组件展示不同系列的图表类型标记、颜色、和名称。可以通过点击来控制哪个系列不展示。对于饼图来说,控制哪个数据不展示。 $> echarts5.4.0简单画一个饼图作为示例,设置legend:{show:true}展示图例。 const options {legend: {show: true,},series…

WMS仓库管理系统研发规划说明

01 产品背景 1.1 背景概述 aboss WMS东南亚仓库管理系统是一个基于BigSeller系统的使用基础上,加上多仓库的解决思路,解决入库业务、出库业务、仓库调拨、库存调拨和虚仓管理等功能,对批次管理、物料对应、库存盘点、质检管理、虚仓管理和即…

Mac与windows传文件(超过4G且速度超快,非共享)

MAC与Windows文件互传 背景 尝试了网上的一些方法,诸如设置共享文件夹方法等,但是实际使用中感觉效果一般,对于一些小的文件共同编辑速度还可以。但是在备份或者传递一些较大文件或者很多细小文件的时候就有点捉襟见肘了。制作了一个MAC可读…

规划模型Matlab代码

文章目录 数学规划定义一般形式分类 1.线性规划(linear programming)2.非线性规划(nonlinear programming)3. 整数规划(integer programming)4. 0-1规划(0-1 programming)5. 最大最小化模型6. 多目标规划模型7.敏感性分析(对权重)[例题] 数学规划定义 数…

基于SSM试题库管理系统

试题库管理系统(基于SSM) 运行环境:JDK 1.8 MySQL 5.7 Tomcat 8.0.53 编码集:UTF-8 IDE:eclipse 4.8.0 数据库 库名: 用户名:root 密码:admin 登录界面: 学生界面: 教师界面…

C++ ------ new关键字和delete关键字

文章目录 C/C内存分布C内存管理方式 operator new 与 operator delete 函数new和delete的实现原理内置类型自定义类型 定位new表达式 C/C内存分布 我们来看下面的一个题目: int globalVar 1; static int staticGlobalVar 1; void Test() {static int staticVar …

使用强化学习破解迷宫实战

大家好,本文将实现一种强化学习算法来解决迷宫问题,并完成以下步骤:创建迷宫环境、定义迷宫类,以及使用值迭代算法(Value Iteration algorithm)找到穿越迷宫的最优策略。为了使这一过程可视化,使…

Stable Diffusion系列课程二:ControlNet

AUTOMATIC1111/stable-diffusion-webui参考B站Nenly视频《零基础学会Stable Diffusion》、视频课件推荐网站:stable-diffusion-art、Civitai(魔法) 、libilibi、AI艺术天堂推荐Stable Diffusion整合资料: NovelAI资源整合、《AI绘…

Flowable-网关-并行网关

目录 定义图形标记XML内容使用示例视频教程 定义 并行网关能在一个流程里用来对并发进行建模处理,它能把单条线路拆分成多个路径并行执 行,或者将多个路径合并处理。在一个流程模型里引入并发最直接的网关就是并行网关,它基于进 入和外出顺序…

回归预测 | MATLAB实现基于SVM-RFE-BP支持向量机递归特征消除特征选择算法结合BP神经网络的多输入单输出回归预测

回归预测 | MATLAB实现基于SVM-RFE-BP支持向量机递归特征消除特征选择算法结合BP神经网络的多输入单输出回归预测 目录 回归预测 | MATLAB实现基于SVM-RFE-BP支持向量机递归特征消除特征选择算法结合BP神经网络的多输入单输出回归预测预测效果基本介绍研究内容程序设计参考资料…

Android Studio中使用cmake开发JNI实战

JNI学习大纲 一、JNI编程入门 二、Android Studio中使用cmake开发JNI实战 第一章节我们介绍了JNI的开发步骤,那这一章节我们就开始在Android Studio中实战一下吧,Lets Start。 1. Android Studio中安装CMake插件 AS中菜单栏选择Tools>SDK Manager在…

Servlet是什么和创建、配置第一个servlet

Servlet是什么和创建、配置第一个servlet servlet是什么 2、创建servlet 方式一: 方式二: 方式三:

vscode中无法使用git解决方案

1 首先查看git安装目录 where git 2 找到bash.exe 的路径 比如:C:/Users/Wangzd/AppData/Local/Programs/Git/bin/bash 3 找到vscode的配置项setting.json 4 添加 "terminal.integrated.shell.windowns": "C:/Users/Wangzd/AppData/Local/Pr…

Python如何解决Amazon亚马逊“图文验证码”识别(6)

前言 本文是该专栏的第55篇,后面会持续分享python爬虫干货知识,记得关注。 在本专栏前面,笔者有详细介绍多种登录验证码识别方法,感兴趣的同学可往前翻阅。而本文,笔者将单独详细介绍亚马逊Amazon的图文识别验证码的解决方法。 如上图所示,访问或请求频次达到一定程度之…