首页 > 其他分享 >TypeScript 学习笔记 — 类的基本用法(五)

TypeScript 学习笔记 — 类的基本用法(五)

时间:2023-02-20 16:11:35浏览次数:40  
标签:TypeScript console name age 笔记 用法 Animal class log

目录

类的组成部分:构造函数、属性(实例属性、原型属性、静态属性)、方法(实例方法、原型方法、静态方法、访问器)

TS 中定义类

实例属性/方法:所有实例上的属性和方法都需要先声明后再使用

class Circle {
  x: number;
  y: number;
  constructor(x: number, y: number = 0, ...args: number[]) {
    // 默认值、剩余运算符
    this.x = x;
    this.y = y;
  }
}
let circle = new Circle(100);

类中实例属性、方法 + 修饰符

上述代码当构造函数参数比较多时,声明就会显得很多,结构不友好,此时需要使用类的修饰符来解决,表示可访问的范围或权限
类的修饰符分类: public (公开的:自己,子类,外界)、protected(受保护的:自己、子类)、private(私有的:自己)、readonly(只读的)

public

class Animal {
  /* 
    public name!: string; // 不写public默认也是公开的
    public age!: number;
    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }
  */
  // 可以简写为:直接在参数前添加对应的修饰符,就会默认添加到实例中,相当于已经声明
  constructor(public name: string, public age: number) {
    this.name = name;
    this.age = age;
  }
}
class Cat extends Animal {
  constructor(name: string, age: number) {
    super(name, age);
    console.log(this.name, this.age); // 子类访问
  }
}
let p = new Cat("Tom", 18);
console.log(p.name, p.age); // 外层访问

protected

class Animal {
  // 可以简写为:直接在参数前添加对应的修饰符,就会默认添加到实例中,相当于已经声明
  constructor(protected name: string, protected age: number) {
    this.name = name;
    this.age = age;
  }
}
class Cat extends Animal {
  constructor(name: string, age: number) {
    super(name, age);
    console.log(this.name, this.age); // 子类访问
  }
}
let p = new Cat("Tom", 18);
console.log(p.name, p.age); // 异常:属性“name”受保护,只能在类“Animal”及其子类中访问

private

class Animal {
  constructor(private name: string, private age: number) {
    this.name = name;
    this.age = age;
  }
}
class Cat extends Animal {
  constructor(name: string, age: number) {
    super(name, age);
    console.log(this.name, this.age); // 异常:属性“name”为私有属性,只能在类“Animal”中访问。
  }
}

let p = new Cat("Tom", 18);
console.log(p.name, p.age); // 异常:属性“name”为私有属性,只能在类“Animal”中访问。

readonly

仅读属性只能在 constructor 中被赋值,因为是相当于初始化

class Animal {
  constructor(public readonly name: string, public age: number) {
    this.name = name; // 仅读属性只能在constructor中被赋值,因为是相当于初始化
    this.age = age;
  }
  changeName(name: string) {
    this.name = name; // 异常:无法分配到 "name" ,因为它是只读属性。
  }
}
class Cat extends Animal {
  constructor(name: string, age: number) {
    super(name, age);
  }
}
let p = new Cat("Tom", 18);
p.changeName("Jerry");

实例方法

class Animal {
  public eat: () => void; // 实例方法
  constructor() {
    this.eat = () => {
      console.log("eat");
    };
  }
}
let an = new Animal();
an.eat();

类中原型属性、方法 + 访问器

原型属性 + 访问器

class Animal {
  private _name: string = "Tom"; //  原型属性
  get name() {
    // 需要通过类的访问器,访问 原型上的属性
    return this._name;
  }
  set name(newValue) {
    this._name = newValue;
  }
}

let an = new Animal();
console.log(an.name);

原型方法

class Animal {
  say(message: string) {
    console.log(message);
  }
}

let an = new Animal();
an.say("hello");

类中静态属性、方法

静态属性、方法都是通过类名直接调用,并且静态属性和静态方法是可以被子类所继承

class Animal {
  static type = "哺乳动物"; // 静态属性
  // 静态方法
  static getName() {
    return "动物类";
  }
}
class Cat extends Animal {}

console.log(Animal.type);
console.log(Animal.getName());
console.log(Cat.type);
console.log(Cat.getName());

子类重写父类方法

要求必须和父类的方法类型一致,也就是说方法的入参与返回值的类型,需要兼容父类方法的类型

class Animal {
  static getType(ms: string) {
    console.log("父");
  }
  say(ms: string): void {
    console.log("父 say");
  }
}
class Mouse extends Animal {
  static getType() {
    console.log("子");
  }
  say() {
    console.log("子 say");
    return 123;
  }
}
let mouse = new Mouse();
mouse.say();
Mouse.getType();

类中 Super 属性

  • 原型方法中的 super 指代父类的原型
  • 静态方法中的 super 指代父类
  • 构造函数中的 super 指代父类
class Animal2 {
  static getType() {
    console.log("父");
  }
  public eat: () => void;
  constructor() {
    this.eat = () => {
      console.log("eat");
    };
  }
  say(): void {
    console.log("父 say");
  }
}

class Mouse extends Animal2 {
  static getType() {
    console.log("子");
    super.getType(); // super 指代父类
  }
  constructor() {
    super(); // super 指代父类
  }
  say() {
    console.log("子 say");
    super.say(); // super 指代父类的原型
  }
}
let mouse = new Mouse();
mouse.say(); // 依次打印:子 say、 父 say、
mouse.eat(); // 打印:子 say、 父 say、
Mouse.getType(); // 依次打印:子、 父

修饰符 + constructor(){}

构造函数中增加了 private 和 protected,表示父类不能被 new,此时使用场景并不是很多,通常多见于单例模式

单例模式

class Singleton {
  static instance = new Singleton();
  private constructor() {} //  默认不写 是public
  static getInstance() {
    return this.instance;
  }
}

// 单例模式
let instance1 = Singleton.getInstance();
let instance2 = Singleton.getInstance();
console.log(instance1 === instance2); // true

抽象类 abstract

抽象类的特点:

  1. abstract修饰的类叫做抽象类,也可以修饰抽象方法
  2. 抽象方法不能在抽象类中实现,只能在抽象类的具体子类中实现,而且必须实现。
  3. 只有抽象类中可以有抽象方法,
  4. 抽象类中可以有普通方法,普通方法不需要被子类重写
  5. 抽象类不能被实例化,也就是不能 new,只能被继承
  6. 定义类型时 void 表示函数的返回值为空(不关心返回值类型,所有在定义函数时也不关心函数返回值类型)
abstract class Animal {
  // 1
  abstract speak(): void; // 3,
  drink() {
    // 4
    console.log("drink");
  }
}
class Cat extends Animal {
  speak() {
    // 2
    console.log("猫叫");
  }
}
class Dog extends Animal {
  speak(): string {
    // 6
    console.log("汪叫");
    return "wangwang";
  }
}

new Animal(); // 5. 报异常:无法创建抽象类的实例

抽象类定义实例方法及原型方法

实例方法

abstract class Person {
  abstract eat: () => void; // 定义实例方法
}
class Teacher extends Person {
  eat: () => void; // 属性“eat” 初始化,且需要在构造函数中明确赋值。
  constructor() {
    super(); // 访问派生类的构造函数中的 this前,必须调用"super"。
    this.eat = function () {
      console.log("eat");
    };
  }
}

原型方法

abstract class Person {
  abstract eat(): void; // 定义原型方法
}
class Teacher extends Person {
  eat(): void {
    // 非抽象类"Teacher"需要实现父类"Person”"的抽象成员"eat"。
    console.log("eat");
  }
}

标签:TypeScript,console,name,age,笔记,用法,Animal,class,log
From: https://www.cnblogs.com/echoyya/p/17099984.html

相关文章

  • 微机原理与系统设计笔记6 | 存储器系统设计
    打算整理汇编语言与接口微机这方面的学习记录。本部分介绍存储器及其扩展方法。参考资料西电《微机原理与系统设计》周佳社西交《微机原理与接口技术》课本《汇......
  • 再次入坑写学习笔记
    魔幻的2022年中中断了写学习笔记的工作。孩子去澳洲上学去了,再次入坑写写学习笔记。孩子在大学中需要用R语言,我也跟着学习起来。R语言主要用于学术研究中的统计、数据挖......
  • MySQL中length()、char_length()的区别和用法
    方法概述:char_length(str)计算单位:字符不管汉字还是数字或者是字母都算是一个字符length(str)计算单位:字节utf8编码:一个汉字三个字节,一个数字或字母一个字节。gbk......
  • Linux学习笔记
    第一章:初识Linux1、LinuxLinux是一套免费和自由传播的类UNIX操作系统(类UNIX系统:是指继承UNIX的设计风格演变出来的系统),是基于POSIX和UNIX的多用户、多任务、支持多线程和......
  • lambda表达式用法
    (参数列表)->{代码块};(inta,intb)->{returna+b;};本质为匿名函数参数的类型可以省略:(a,b)->{returna+b;}当参数只有一个的时候,可以省略():a->{returna*a;};......
  • JAVA笔记
    基础知识数据类型面向对象......
  • typescript+vue3使用vue-ls
    npmivue-ls新建storage.tsimportStoragefrom'vue-ls';constoptions={namespace:'vuejs__',//keyprefixname:'ls',//namevariableVue.[ls]ort......
  • 微信小程序全局变量(globalData)和缓存(StorageSync)的区别和用法
    globalData和storage的区别一、app.globalData是全局变量,下次进入的时候,就要重新获取,一般用于:1、保存一些可能涉及安全类的数据,例如资源类,每次需要很准确的,就建议用全......
  • springMVC中的ModelMap作用及用法
    概念ModelMap的作用:ModelMap对象主要用于传递控制方法传递数据到结果页面。类似于request的setAttribute方法的作用。所以我们要想在jsp页面获取数据,只要将数据放到ModelMa......
  • Java面试宝典_君哥讲解笔记03java基础——浮点型计算为什么会有精度丢失、在不使用第
    java基础面试题文章目录文章目录​​java基础面试题文章目录​​​​前言​​​​浮点型计算为什么会有精度丢失?该怎么解决精度丢失的问题​​​​在不使用第三变量的情况下......