TypeScript 类

news2024/11/23 2:46:43

类在面向对象编程中起着创建对象的蓝图,描述所创建的对象共同的属性和方法的作用。

创建类

与JS差不多,通过 Class 关键字来定义一个类:

class Greeter {
  // 静态属性
  static cname: string = "Greeter";
  // 成员属性
  greeting: string;

  // 构造函数 - 执行初始化操作
  constructor(message: string) {
    this.greeting = message;
  }

  // 静态方法
  static getClassName() {
    return "Class name is Greeter";
  }

  // 成员方法
  greet() {
    return "Hello, " + this.greeting;
  }
}

let greeter = new Greeter("world");

接下来逐步讲解:

static cname:如果属性用static修饰的话(默认为public),表示静态属性不能通过实例对象访问到该属性,只能在类内调用或者通过类去访问,比如 Person.gender。

static getClassName:通过static修饰该方法(默认为public),表示静态方法 ,不能通过实例对象访问到该方法需要在类内调用或通过类去访问 ,比如 Person.sayHello()

构造函数:类的构造函数,对象创建时调用 限制。每个类仅能一个构造函数

this的指向:

1、在实例方法中,this就表示当前的实例
2、在构造函数中的当前对象就是新建的那个对象
 3、可以通过this向新建的对象中添加属性

看看JS是怎么实现的:

var Greeter = /** @class */ (function () {
    // 构造函数 - 执行初始化操作
    function Greeter(message) {
        this.greeting = message;
    }
    // 静态方法
    Greeter.getClassName = function () {
        return "Class name is Greeter";
    };
    // 成员方法
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    // 静态属性
    Greeter.cname = "Greeter";
    return Greeter;
}());
var greeter = new Greeter("world");

可以看到常态方法greet生成了对象原型链上的方法,静态方法static生成了对象上的方法。而无论是静态属性或者常态属性都是挂靠在对象上面。匿名函数返回了Greeter方法并立即执行。

class Greeter {
    // 静态属性
    static cname: string = 'dd'
    // 成员属性
    greeting: string = 'ff';
  }

var Greeter = /** @class */ (function () {
    function Greeter() {
        // 成员属性
        this.greeting = 'ff';
    }
    // 静态属性
    Greeter.cname = 'dd';
    return Greeter;
}());

没有默认值的话连属性都不会生成

class Greeter {
    // 静态属性
    static cname: string 
    // 成员属性
    greeting: string ;
  }

var Greeter = /** @class */ (function () {
    function Greeter() {
    }
    return Greeter;
}());

如果我们用ES6的Class类来实现TS的Greeter类。则:

class Greeter {
    // 静态属性
    cname= "Greeter";
    // 成员属性
    greeting;
  
    // 构造函数 - 执行初始化操作
    constructor(message) {
      this.greeting = message;
    }
  
    // 静态方法
    static getClassName() {
      return "Class name is Greeter";
    }
  
    // 成员方法
    greet() {
      return "Hello, " + this.greeting;
    }
  }
  

注意ES6没有静态属性static,只有静态方法。

继承类

class Animal{
    name:string
    age:number
    //构造函数
    constructor(name:string,age:number){
        this.name = name
        this.age = age
    }
    // 自定义方法
    sayHello(){
        console.log('动物在叫~')
    }
  }  

  class Dog extends Animal{
    // 重写父类方法
    sayHello(): void {
        console.log('汪汪汪')
    }
  }

  class Cat extends Animal{
    //重写父类方法
    sayHello(): void {
        console.log('喵喵喵')
   }
  }

  const dog = new Dog('旺财',4) 
  const cat = new Cat('咪咪',3)
  console.log(dog) //Dog {name: '旺财', age: 4}
  console.log(dog.sayHello()) //汪汪汪
  console.log(cat) //Cat {name: '咪咪', age: 3}
  console.log(cat.sayHello()) //喵喵喵

直接看代码:

Dog extends Animal

  •   此时,Animal被称为父类,Dog被称为子类
  •   使用继承后,子类将会拥有父类所有的方法和属性
  •   通过继承可以将多个类中共有的代码写在一个父类中,
  •   这样只需要写一次即可让所有的子类都同时拥有父类中的属性和方法
  •   如果希望在子类中添加一些父类中没有的属性或方法直接加就行
  •   这种子类覆盖掉父类方法的形式,我们称为方法重写

继承类的构造函数constructor可以不用写。默认会沿用父类的构造函数。

继承也可以用于interface接口身上。

interface a {
    name:string
}
interface b extends a {
    age:number
}
let obj :b = {name:'ss',age:3}

super方法

class Animal{
        name:string
        age:number
        constructor(name:string,age:number){
            this.name = name
            this.age = age            
        }
        sayHello(){
            console.log('动物在叫~')
        }
}
class Dog extends Animal{
        //子类构造函数
        constructor(name:string,age:number){
            super(name,age)
        }

        //重写父类方法
        sayHello(): void {
            super.sayHello()
            console.log('汪汪汪')
        }
}
  
const dog = new Dog('旺财',2)
console.log(dog) //Dog {name: '旺财', age: 2}
console.log(dog.sayHello()) //动物在叫~   汪汪汪

 super: 调用父类构造函数
场景:如果在子类中写了构造函数,在子类构造函数中"必须"对父类的构造函数进行调用
在类的方法中 super就表示当前类的父类   super.sayHello();

抽象类abstract

  • 以abstract开头的类是抽象类
  • 抽象类和其他类区别不大,只是不能用来创建对象
  • 抽象类就是专门用来被继承的类
  • 抽象类中可以添加抽象方法
 abstract class Animal{
    name: string;
    constructor(name: string) {
        this.name = name;
    }
    abstract sayHello():void //只能这样写 不能有具体实现什么 否则报错
} 

注意抽象类的方法是不能有函数体的。抽象方法只能定义在抽象类中,子类必须对抽象方法进行重写。

   class Dog extends Animal{
        //注意:必须要重写父类,抽象的方法,不然会报错
        sayHello():void {
            console.log('汪汪汪')
        }
   }

private、public、protected和访问器

TS可以在属性前添加属性的修饰符

 class Person{
          private _name:string
          private _age:number
          constructor(name:string,age:number){
              this._name = name
              this._age = age
          }
          setName(value){
              this._name = value
          }
          getName(){
              return this._name
          }
}

        上文提到加了static静态修饰的属性虽然不能通过实例去获取,但是它可以通过类的属性去获取(比如Person.name)。如果我们希望其无法通过任何渠道去获取。那就可以使用private修饰。

        如果你想要让私有属性能够在外部被访问被修改。就像上文一样,在类内部添加方法暴露私有属性。

  •  public 修饰的属性可以在任意位置访问(修改)默认值
  •  private 私有属性,私有属性只能在类内部进行访问(修改)
  • 通过在类中添加方法使得私有属性可以被外部访问
  • protected 受保护的属性,只能在当前类和当前类的子类中访问(修改)

         而实际上,TS已经贴心的为我们提供了访问器队私密属性进行操作。不需要我们在类中添加方法。

        TS中设置getter方法的方式: 此时再使用personA.name时,实际上是调用了get name()方法。

class Person{
    private _name:string
    ...
    get name() {
      return this._name;
    }
}

        调用:

let personA = new Person('dd',12);
console.log(personA.name)

        TS中设置setter方法的方式:此时再使用personA.name = xxx时,实际上是调用了set name()方法!

set name(value) {
    this._name = value;
}

        调用:

personA.name ='xxxxx'

protected修饰:

但是如果是这样就可以:

 const b = new B(123);
console.log(b.test())

 

interface接口

接口用来定义一个类结构,用来定义一个类中应该包含哪些属性和方法
同时接口也可以当成类型声明去使用
可以定义相同的接口,最后会合并在一起
接口里面的属性和方法不能有初始值
接口只考虑对象结构,而不考虑实际值
在接口中定义方法都是抽象方法,也就意味着需要重写

interface myinterface {
        name:string,
        age:number
   }
interface myinterface{
        gender:string
        sayHello():void
}
let aaaa:myinterface ={name:'a',age:33,gender:'xx',sayHello:()=>{console.log(123)}}

而定义类时,可以使类去实现一个接口。实现接口就是使类满足接口的要求

  class myClass implements myinterface{
        constructor(public name:string, public age:number,public gender:string){
            this.name = name
            this.age = age
            this.gender = gender
        }
        sayHello() {
            console.log('你好呀~')
        }
}

泛型与类

使用场景:在定义函数或类时,如果遇到类型不明确就可以使用泛型

具体请看我的另外一篇推文。TS与泛型

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

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

相关文章

音乐格式转换mp3怎么转?跟着步骤操作一遍

音乐格式转换mp3怎么转?mp3,一种音频数据压缩格式,由于其极具优势的文件尺寸小和高质量音效,自诞生之日起就占据了主流音乐格式的头把交椅,并且至今仍然受到用户的青睐,稳居音乐领域的霸主地位。在我们繁忙…

Postman接口压力测试 ---- Tests使用(断言)

所谓断言,主要用于测试返回的数据结果进行匹配判断,匹配成功返回PASS,失败返回FAIL。 下图方法一,直接点击右侧例子函数,会自动生成出现在左侧窗口脚本,只需修改数据即可。 方法二:直接自己写脚…

前端实现页面通过canvas添加全屏水印

写在前面,博主是个在北京打拼的码农,从事前端工作5年了,做过十多个大大小小不同类型的项目,最近心血来潮在这儿写点东西,欢迎大家多多指教。 对于文章中出现的任何错误请大家批评指出,一定及时修改。有任何…

【STM32】片上ADC的初步使用

基于stm32f103系列 基于《零死角玩转 STM32F103—指南者》 ADC简介 stm32f103上的ADC 数量:3 精度:12bit(4096) 通道:ADC1,ADC2均有16个通道,ADC3有8个 功能:   转换结束、注入转换结束和发生模拟看门狗事件时产生中断。   …

Git入门图文教程(深入浅出,详细了解Git,以及操作)

01、认识一下Git!—简介 Git是当前最先进、最主流的分布式版本控制系统,免费、开源!核心能力就是版本控制。再具体一点,就是面向代码文件的版本控制,代码的任何修改历史都会被记录管理起来,意味着可以恢复…

HCS 中的一些概念

一、HCS功能层 1、基础设施:服务器、存储、网络、防火墙…… 2、资源池:Fusion Sphere OpenStack资源池、虚拟化资源池、裸金属服务器池、块存储池、文件存储池、网络资源池灾备资源池…… 3、管理域:ManageOne提供多个数据中心的统一管理和调…

解决:华为ensp软件中AR和AC,AP设备无法启动报错“40”的问题

AR为路由器设备,AC,AP为无线局域网设备。 报错信息 报错原因以及解决方案: 1.系统虚拟化hyper-v正在运行 计算机安装过virtualBox,Vmvere之类的虚拟化软件,默认系统虚拟化安全性属于运行状态。 解决方案: 1.搜索cm…

数字展厅是什么,数字展厅有哪些优势?

引言: 随着数字化时代的到来,宣传领域也发生了巨大的变革。数字展厅是一种全新的宣传工具,正在逐渐崭露头角,作为现代宣传领域的一项重要创新,在迅速改变传统展厅的面貌。 一.什么是数字展厅? …

LinkedHashMap源码分析

特性 在 HashMap 基础上维护一条双向链表 支持遍历时会按照插入顺序有序进行迭代。LinkedHashMap 的迭代顺序是和插入顺序一致的,这一点是 HashMap 所不具备的。 。支持按照元素访问顺序排序,适用于封装 LRU 缓存工具。 因为内部使用双向链表维护各个节点,所以遍历…

北峰北斗短报文在应急通信的应用

随着社会的发展,自然灾害、交通事故等突发事件的频繁发生,让人们知道通信设备的可靠性尤为重要。北斗短报文应急通信作为一种新型的通信方式,具有较高的可靠性和应用价值。尤其是在灾区移动通讯中断,电力中断或移动通信无法覆盖北…

React 之 Hooks解析

一、概念 1. class组件的优势 class组件可以定义自己的state,用来保存组件自己内部的状态 函数式组件不可以,因为函数每次调用都会产生新的临时变量class组件有自己的生命周期,我们可以在对应的生命周期中完成自己的逻辑,比如在…

使用Postman拦截浏览器请求

项目上线之后,难免会有BUG。在出现问题的时候,我们可能需要获取前端页面发送请求的数据,然后在测试环境发送相同的数据将问题复现。手动构建数据是挺麻烦的一件事,所以我们可以借助Postman在浏览器上的插件帮助拦截请求&#xff0…

2023最新PDF阅读器评测

评测说明 本人程序员,平时阅读为主。以下为主观实际体验感受为主。 软件选择 以无广、可免费使用为基本要求。Adobe Reader 自不必说。 体验软件 SumatraPDF 特点:简洁。开源免费的小个子软件,当前最新安装包只有7M,启动速度很…

【初阶算法4】——归并排序的详解,及其归并排序的扩展

目录 前言 学习目标: 学习内容: 一、介绍归并排序 1.1 归并排序的思路 1.2 归并排序的代码 1.2.1 mergesort函数部分 1.2.2 process函数部分 1.2.3 merge函数部分 二、AC两道经典的OJ题目 题目一:逆序对问题 题目二&#xff1…

笔记本选购指南

大学生笔记本电脑选购指南 文章目录 笔记本分类指标排行 了解自身需求理工科文科艺术总结 参考指标品牌CPU显卡屏幕其他 购买渠道推荐游戏本Redmi G 锐龙版联想G5000惠普光影精灵9天选4锐龙版联想R7000P暗影精灵9联想拯救者R9000P 全能本华硕无畏PRO15联想小新Pro14 2023 轻薄本…

react ant ice3 实现点击一级菜单自动打开它下面最深的第一个子菜单

1.问题 默认的如果没有你的菜单结构是这样的: [{children: [{name: "通用配置"parentId: "1744857774620672"path: "basic"}],name: "系统管理"parentId: "-1"path: "system"} ]可以看到每层菜单的p…

期权投资的优势有哪些方面?

随着金融市场的不断演变,越来越多的金融衍生品出现在人们的视线中,特别是上证50ETF期权可以做空T0的交易模式吸引了越来越多的朋友,那么期权投资的优势有哪些方面? 期权是投资市场中一个非常重要的投资方式,期权投资能…

SOLIDWORKS装配体如何使用全局变量

客户痛点:随着人力资源价格的增长,设计的时间需要减少时间,提高设计效率。 数据问题:以前单个数据都需要建立单独的数据结构,装配体的模型都要重新建立。 需要解决的问题:能够快速地完成3D模型及装配体的…

TensorFlow 03(Keras)

一、tf.keras tf.keras是TensorFlow 2.0的高阶API接口,为TensorFlow的代码提供了新的风格和设计模式,大大提升了TF代码的简洁性和复用性,官方也推荐使用tf.keras来进行模型设计和开发。 1.1 tf.keras中常用模块 如下表所示: 1.2 常用方法 …

机器学习——协同过滤算法(CF)

机器学习——协同过滤算法(CF) 文章目录 前言一、基于用户的协同过滤1.1. 原理1.2. 算法步骤1.3. 代码实现 二、基于物品的协同过滤2.1. 原理2.2. 算法步骤2.3. 代码实现 三、比较与总结四、实例解析总结 前言 协同过滤算法是一种常用的推荐系统算法&am…