当前位置: 首页 > news >正文

TypeScript实用笔记(二):类与接口详解

文章目录

  • 一、 constructor()
  • 二、 调用父类的构造函数
    • 1. 有constructor的继承
    • 2. 无constructor的继承
  • 三、 接口interface的实现
    • 1. 实现接口
    • 2. 接口继承
    • 3. 总结
  • 四、访问修饰符
    • 1. private
    • 2. protected
    • 3. public
    • 4. readonly
    • 5. abstract
    • 6. static
    • 7. 访问范围总结
        • 7.1 访问范围
        • 7.2 示例

TypeScript实用笔记(一):初始化、类型定义与函数使用
TypeScript实用笔记(二):类与接口详解
TypeScript实用笔记(三):泛型的使用 && 的12种工具类型的使用

一、 constructor()

  • constructor 是一个特殊的方法,用于初始化对象的实例。当创建一个类的实例时,constructor 方法会被自动调用。它的主要作用是设置实例的初始状态,通常包括初始化属性和执行必要的启动代码。
  • 每个类只能有 <= 一个constructor
class Car {/*** make 和 model 是 Car 类的属性* 在类中定义这些属性是必要的,以便能够在 constructor 中使用 this.make 和 this.model 进行赋值。* 如果没有这些属性的定义,TypeScript 将会报错,提示无法找到这些属性* 如果属性不设定默认值或者设置为可选项,那么在constructor时必须赋值*/make: string; //设置默认值:make: string | undefined;model: string; //参数设置为可选项:model?: stringconstructor(make: string, model: string) {this.make = make;this.model = model;}
}const myCar = new Car("Toyota", "Corolla");
console.log(myCar.make); // 输出: Toyota

二、 调用父类的构造函数

  • 子类可以重写父类的方法,如果不进行重写,则可直接调用。

1. 有constructor的继承

  • 显式构造函数:如果子类定义了一个 constructor,则必须在该构造函数中调用父类的构造函数,通常使用 super()
  • 参数传递:子类的构造函数可以接收参数,并可以将这些参数传递给父类的构造函数。
  • 初始化:在子类构造函数中,可以初始化子类特有的属性。
//定义一个父类 Animal
class Animal {//父类属性name: string;//构造函数constructor(name: string) {this.name = name;}//父类方法speak() {console.log(`${this.name} makes a noise.`);}speak2() {console.log(`this is speak2.`);}}//定义一个子类 Dog 继承自 Animal
class Dog extends Animal {//子类特有的属性breed: string;//子类构造函数constructor(name: string, breed: string) {//调用父类的构造函数super(name); //先调用父类的构造函数以初始化父类属性this.breed = breed; //初始化子类特有属性}//重写父类的方法speak() {console.log(`${this.name} barks.`);}
}//创建一个 Animal 实例
const animal = new Animal("Generic Animal", 5);
animal.speak(); //输出: Generic Animal makes a noise.//创建一个 Dog 实例
const dog = new Dog("Buddy", 3, "Golden Retriever");
dog.speak(); //输出: Buddy barks.
dog.speak2(); //输出: this is speak2.
console.log(`${dog.name} is a ${dog.breed}.`); //输出: Buddy is a Golden Retriever.

2. 无constructor的继承

  • 隐式构造函数:如果子类没有定义 constructor,则 JavaScript 引擎会自动创建一个隐式构造函数。在这种情况下,父类的构造函数会被自动调用。
  • 无法传递参数:子类将不能接收参数或进行特定的初始化操作,除非父类构造函数接受的参数是默认的。
class Animal {name: string;constructor(name: string) {this.name = name;}
}class Cat extends Animal {//没有显式的 constructormeow() {console.log(`${this.name} says Meow!`);}
}const myCat = new Cat("Whiskers"); //调用父类构造函数. 虽然子类没有显式的constructor,但因为父类有未赋值的初始参数,所以子类调用的时候需要传父类name值
console.log(myCat.name); //输出: Whiskers
myCat.meow(); //输出: Whiskers says Meow!

三、 接口interface的实现

  • 定义接口:使用 interface 关键字定义一个接口。
  • 实现接口:在类的声明中使用 implements 关键字,表示该类实现了该接口。
  • 实现接口中的属性和方法:类++必须实现++接口中定义的所有属性和方法。

1. 实现接口

//定义一个接口
interface Vehicle {make: string;       //属性model: string;      //属性start(): void;      //方法
}//实现接口的类
class Car implements Vehicle {make: string;model: string;constructor(make: string, model: string) {this.make = make;this.model = model;}//实现接口中的方法start() {console.log(`The ${this.make} ${this.model} is starting.`);}
}//创建一个 Car 实例
const myCar = new Car("Toyota", "Corolla");
myCar.start(); //输出: The Toyota Corolla is starting.

2. 接口继承

//定义一个基础接口
interface Engine {start(): void;
}//定义一个更复杂的接口,继承 Engine
interface Vehicle extends Engine {make: string;model: string;
}//实现继承的接口
class Motorcycle implements Vehicle {make: string;model: string;constructor(make: string, model: string) {this.make = make;this.model = model;}start() {console.log(`The ${this.make} ${this.model} motorcycle is starting.`);}
}//创建 Motorcycle 实例
const myBike = new Motorcycle("Honda", "CBR");
myBike.start(); //输出: The Honda CBR motorcycle is starting.

3. 总结

  1. 接口定义了一组期望的属性和方法,类在实现接口时必须遵循这些规则。这有助于捕捉潜在的错误,并在编译时提供类型检查。
  2. 类通过实现接口来确保符合特定的结构,提供了一种强类型的方式来定义对象的形状和行为。使用接口使得代码更易于理解和维护,同时也增强了类型安全。
  3. 接口可以清晰地表示类之间的依赖关系,帮助在测试时更好地理解对象之间的交互。

四、访问修饰符

只能用于++类中的属性和方法++,不能用于其他类型的声明(例如,接口、函数等)。

public 是默认的访问修饰符,若未指定,则默认为 public

1. private

  • private 表示类的属性和方法只能在类的内部访问,不能在类的实例或子类中直接访问。
  • 当一个类被继承时,子类无法直接访问父类中定义的 private 成员。
class BankAccount {private balance: number; // 私有属性constructor(initialBalance: number) {this.balance = initialBalance; // 在构造函数中初始化私有属性}public deposit(amount: number) {if (amount > 0) {this.balance += amount;console.log(`Deposited: ${amount}. New balance: ${this.balance}`);}}public withdraw(amount: number) {if (amount > 0 && amount <= this.balance) {this.balance -= amount;console.log(`Withdrawn: ${amount}. New balance: ${this.balance}`);} else {console.log("Insufficient funds.");}}
}const account = new BankAccount(100);
account.deposit(50); // 输出: Deposited: 50. New balance: 150
// 下面的代码会报错,因为 balance 是私有的
// console.log(account.balance); // Error: Property 'balance' is private and only accessible within class 'BankAccount'.

2. protected

  • protected 表示类的属性和方法只能在类内部和其子类中访问,外部代码无法直接访问这些成员。
class Animal {protected species: string; // 受保护的属性constructor(species: string) {this.species = species;}protected makeSound() { // 受保护的方法console.log(`${this.species} makes a sound.`);}
}class Dog extends Animal {constructor() {super("Dog");}bark() {this.makeSound(); // 子类可以访问受保护的方法console.log("Woof!");}
}const dog = new Dog();
dog.bark(); // 输出: Dog makes a sound. Woof!// 下面的代码会报错,因为 species 和 makeSound 是受保护的
// console.log(dog.species); // Error: Property 'species' is protected and only accessible within class 'Animal' and its subclasses.
// dog.makeSound(); // Error: Method 'makeSound' is protected and only accessible within class 'Animal' and its subclasses.

3. public

  • public 是默认的访问修饰符,表示类的属性和方法可以被任何地方访问,包括类的实例、子类和外部代码。
class Person {public name: string; // 公有属性constructor(name: string) {this.name = name;}public greet() { // 公有方法console.log(`Hello, my name is ${this.name}.`);}
}const person = new Person("Alice");
console.log(person.name); // 输出: Alice
person.greet();          // 输出: Hello, my name is Alice.

4. readonly

  • 表示该成员是只读的,不能被修改。用于定义常量属性,只接受首次赋值。
class Example {readonly readonlyProperty: string;constructor(str: string) {this.readonlyProperty = str;}
}const example = new Example("I am readonly!");
//example.readonlyProperty = "New Value"; // 错误:只读属性不能被修改
console.log(example.readonlyProperty); // 正确访问

5. abstract

  • 用于定义抽象类和抽象方法。抽象类不能被实例化,必须由子类实现抽象方法
  • 用于创建一个基本类,提供公共接口给子类。
abstract class Animal {abstract makeSound(): void; //抽象方法,告诉你有一个方法,但是子类自行写,但必须有move() {console.log("Moving...");}
}class Dog extends Animal {makeSound() {console.log("Woof!");}
}const dog = new Dog();
dog.makeSound(); //输出: Woof!
dog.move(); //输出: Moving...

6. static

  • 表示该成员是静态的,属于类本身而不是类的实例。不需要实例化Class,就可以直接调用里面的static成员
  • 用于定义类级别的属性和方法。
class Example {static staticProperty: string = "I am static!";static staticMethod() {console.log("This is a static method.");}
}console.log(Example.staticProperty); //正确访问静态属性
Example.staticMethod(); //正确调用静态方法

7. 访问范围总结

7.1 访问范围
修饰符类内部子类类实例类外部
private
protected
abstract
static
readonly
public
7.2 示例
//protected 4种范围示例
class Animal {protected sound: string;constructor(sound: string) {this.sound = sound;}//类内部访问:可以在类内访问 protected 成员makeSound() {console.log(`Animal makes sound: ${this.sound}`);}
}class Dog extends Animal {constructor() {super("Woof");}//子类内部访问:可以在子类中访问父类的 protected 成员bark() {console.log(`Dog barks: ${this.sound}`);}
}const animal = new Animal("Generic Sound");
animal.makeSound(); //正确:类内部方法调用const dog = new Dog();
dog.bark(); //正确:子类内部方法调用//以下访问会报错:无法通过实例直接访问或在类外部访问 protected 成员
console.log(animal.sound); //错误:无法通过类实例访问 protected 成员
console.log(dog.sound);    //错误:无法通过子类实例访问 protected 成员

http://www.mrgr.cn/news/65308.html

相关文章:

  • ubuntu20.04 加固方案-设置用户缺省UMASK
  • VB中的代码重构(Code Refactoring)实践及其好处。
  • Java第九天(实训学习(八)练习题)
  • c++ 贪心算法
  • 什么是 OpenTelemetry?
  • 数据结构 ——— 链式二叉树的前中后序遍历解析
  • Spectrum 绘制调色板:实现与应用指南
  • 构建本地RAG知识库(上): langchain+ollama构建本地大模型应用
  • gRPC-4种通信模式
  • ChatGPT:真如吹的那般神乎其神吗?
  • pdf 添加页眉页脚,获取前五页
  • SpringBoot新闻稿件管理系统:架构与实现
  • 编程模拟生产者和消费者问题(java)
  • Qt6 CMake 中引入 Qt Linguist 翻译功能
  • LeetCode每日一题633---平方数之和
  • runner,hook介绍
  • 在Java中如何创建一个类和对象?
  • Chromium127编译指南 Mac篇(一)- 环境准备详解
  • [实战-11] FlinkSql 设置时区对TIMESTAMP和TIMESTAMP_LTZ的影响
  • 每日一问:什么是SQL注入?注入方式和预防方法有哪些?
  • 100种算法【Python版】第35篇——PageRank算法
  • Java中的排序
  • 爱普生SG-8101CA可编程晶振应用在工业自动化机器人
  • 从0开始学习Linux——文本编辑器
  • java动态导入导出excel,javassist动态创建类
  • C/C++ stackful 有栈协同程式的一些缺点。