首页 > 其他分享 >「TypeScript系列」TypeScript 类/类继承

「TypeScript系列」TypeScript 类/类继承

时间:2024-05-26 10:33:35浏览次数:18  
标签:TypeScript console string 继承 系列 方法 class log

文章目录

一、TypeScript 类

在 TypeScript 中,类(Class)是面向对象编程(OOP)的基本构建块之一。TypeScript 提供了基于类的面向对象编程的语法,这允许你定义类、属性和方法,以及实现继承、封装和多态等面向对象的概念。

下面是一个简单的 TypeScript 类的示例:

class Animal {
    // 属性
    name: string;

    // 构造函数
    constructor(name: string) {
        this.name = name;
    }

    // 方法
    eat(): void {
        console.log(`${this.name} is eating.`);
    }

    // 另一个方法
    speak(): void {
        // 在 Animal 类中,我们不知道如何具体“说”,所以可能只是一个占位符
        console.log(`${this.name} makes a noise.`);
    }
}

// 创建一个 Animal 实例
let dog = new Animal("Buddy");

// 调用方法
dog.eat(); // 输出: Buddy is eating.
dog.speak(); // 输出: Buddy makes a noise.

在上面的示例中,我们定义了一个名为 Animal 的类,它有一个 name 属性、一个构造函数和两个方法:eatspeakconstructor 方法是特殊的,它会在创建类的实例时自动调用,用于初始化类的属性。

二、TypeScript 类继承

TypeScript 中的类可以继承自另一个类,这允许你创建具有层次结构的类。在子类中,你可以添加新的属性和方法,也可以重写从父类继承的属性和方法。

class Dog extends Animal {
    // 继承自 Animal 的属性(包括 name)和方法(包括 eat 和 speak)

    // 添加 Dog 特有的属性
    barkVolume: number;

    // 覆盖父类的 speak 方法
    speak(): void {
        console.log(`${this.name} barks.`);
    }

    // Dog 特有的方法
    bark(): void {
        console.log(`${this.name} barks loudly with volume ${this.barkVolume}.`);
    }

    // 构造函数,需要调用 super() 来初始化父类的属性
    constructor(name: string, barkVolume: number) {
        super(name); // 调用父类的构造函数
        this.barkVolume = barkVolume;
    }
}

// 创建一个 Dog 实例
let d = new Dog("Mitzie", 5);

// 调用从 Animal 继承的方法
d.eat(); // 输出: Mitzie is eating.

// 调用 Dog 类特有的方法
d.bark(); // 输出: Mitzie barks loudly with volume 5.

// 调用被覆盖的 speak 方法
d.speak(); // 输出: Mitzie barks.

在上面的例子中,Dog 类继承自 Animal 类,并添加了一个新的属性 barkVolume 和两个新的方法 barkspeak(其中 speak 方法重写了父类的方法)。在 Dog 类的构造函数中,我们使用 super() 关键字来调用父类的构造函数,以初始化从父类继承的属性。

三、TypeScript 类-关键字

  1. class:用于声明一个类。
class MyClass {
    // ...
}
  1. constructor:用于声明类的构造函数。
class MyClass {
    constructor() {
        // 初始化代码
    }
}
  1. super:在子类构造函数中用于调用父类构造函数。也可以用于访问父类的成员。
class Parent {
    constructor() { /* ... */ }
}

class Child extends Parent {
    constructor() {
        super(); // 调用父类构造函数
    }
}
  1. extends:用于声明一个类继承自另一个类。
class Parent { /* ... */ }

class Child extends Parent { /* ... */ }
  1. implements:用于声明一个类实现了某个接口。
interface MyInterface {
    method(): void;
}

class MyClass implements MyInterface {
    method() {
        // 实现接口方法
    }
}
  1. readonly:用于声明只读属性,这些属性只能在构造函数中被赋值。
class MyClass {
    readonly myProp: string;

    constructor() {
        this.myProp = 'hello'; // 正确
    }

    myMethod() {
        this.myProp = 'world'; // 错误,因为 myProp 是只读的
    }
}
  1. publicprivateprotected:用于指定类成员的访问修饰符。
class MyClass {
    public publicProp: string; // 可以在任何地方访问
    private privateProp: string; // 只能在类内部访问
    protected protectedProp: string; // 可以在类内部和子类内部访问
}

四、TypeScript 类-运算符

在 TypeScript 类中,主要的运算符是点运算符(.),用于访问对象的属性和方法。

class MyClass {
    myProp: string = 'hello';

    myMethod() {
        console.log(this.myProp);
    }
}

const obj = new MyClass();
console.log(obj.myProp); // 使用点运算符访问属性
obj.myMethod(); // 使用点运算符调用方法

五、TypeScript 类-重写(Override)

在 TypeScript 中,子类可以重写父类的方法。为了明确表明一个方法是重写的,你可以使用 override 关键字(从 TypeScript 4.3 版本开始)。这样做有助于提供更强的类型检查和更好的代码可读性。

class Parent {
    method() {
        // ...
    }
}

class Child extends Parent {
    override method() {
        // 重写父类方法
    }
}

如果子类中的方法没有使用 override 关键字,但实际上是重写了父类的方法,并且父类的方法在后续版本中发生了更改(例如,方法签名改变了),那么 TypeScript 编译器可能不会给出明确的错误提示,这可能会导致运行时错误。因此,使用 override 关键字是一种好的做法,可以提高代码的可维护性和健壮性。

六、TypeScript 类-访问控制修饰符

在 TypeScript 中,访问控制修饰符(Access Modifiers)用于指定类成员的可见性和可访问性。TypeScript 支持三种访问控制修饰符:publicprivateprotected

1. public

  • 默认修饰符,如果省略则默认为 public
  • 成员可以在任何地方被访问:类的内部、子类,或者类的实例。
class MyClass {
    public myPublicProp: string = 'Hello';

    public myPublicMethod() {
        console.log(this.myPublicProp);
    }
}

const obj = new MyClass();
console.log(obj.myPublicProp); // 访问类实例的公共属性
obj.myPublicMethod(); // 调用类实例的公共方法

2. private

  • 成员只能在类的内部被访问。
  • 不能在类的外部(包括子类)访问。
class MyClass {
    private myPrivateProp: string = 'Hello';

    public myPublicMethod() {
        console.log(this.myPrivateProp); // 可以在类内部访问
    }
}

const obj = new MyClass();
console.log(obj.myPrivateProp); // 错误:'myPrivateProp' 是私有的

3. protected

  • 成员可以在类的内部和子类中访问。
  • 不能在类的外部(不包括子类)访问。
class ParentClass {
    protected myProtectedProp: string = 'Hello';

    protected myProtectedMethod() {
        console.log(this.myProtectedProp);
    }
}

class ChildClass extends ParentClass {
    public accessProtectedMember() {
        console.log(this.myProtectedProp); // 可以在子类中访问
        this.myProtectedMethod(); // 可以在子类中调用父类的保护方法
    }
}

const obj = new ChildClass();
console.log(obj.myProtectedProp); // 错误:'myProtectedProp' 是受保护的

访问控制修饰符对于封装和隐藏类的内部状态特别有用,它们允许你定义哪些成员是公开的(可以被外部使用),哪些成员是私有的(只能在类内部使用),以及哪些成员是受保护的(可以在类内部和子类中使用)。这有助于创建更加模块化和可维护的代码。

七、TypeScript 类和接口

在 TypeScript 中,类和接口是两个核心概念,它们用于定义和组织代码的结构。

1. 类 (Classes)

类是一种用户定义的类型,它表示具有相同属性和方法的对象的集合。在 TypeScript 中,你可以使用类来创建对象,并通过继承来创建更复杂的对象层次结构。

以下是一个简单的 TypeScript 类的例子:

class Greeter {
    greeting: string;

    constructor(message: string) {
        this.greeting = message;
    }

    greet() {
        return "Hello, " + this.greeting;
    }
}

let greeter = new Greeter("world");
console.log(greeter.greet()); // 输出 "Hello, world"

在这个例子中,Greeter 是一个类,它有一个 greeting 属性和一个 greet 方法。constructor 是一个特殊的方法,用于初始化新创建的对象。

2. 接口 (Interfaces)

接口定义了一个对象的结构,但不包含实现细节。接口定义了一组方法的签名(但不包括方法体),以及一个对象可以拥有的任何属性。

TypeScript 中的接口可以帮助你确保类或其他类型遵循特定的契约(contract)。如果某个类实现了某个接口,那么它必须包含该接口中定义的所有属性和方法。

以下是一个简单的 TypeScript 接口的例子:

interface Person {
    firstName: string;
    lastName: string;
    sayHello(): string;
}

class Employee implements Person {
    firstName: string;
    lastName: string;

    constructor(firstName: string, lastName: string) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    sayHello(): string {
        return `Hello, my name is ${this.firstName} ${this.lastName}`;
    }
}

let employee = new Employee("John", "Doe");
console.log(employee.sayHello()); // 输出 "Hello, my name is John Doe"

在这个例子中,Person 是一个接口,它定义了 firstNamelastName 属性和 sayHello 方法。Employee 类实现了 Person 接口,因此它必须包含这些属性和方法。

接口还可以用于定义对象的形状,而不必明确它是否是类。这对于描述函数参数的类型特别有用:

function greet(person: Person) {
    return person.sayHello();
}

let user = {
    firstName: "Jane",
    lastName: "Doe",
    sayHello: function() {
        return `Hello, I'm ${this.firstName} ${this.lastName}`;
    }
};

console.log(greet(user)); // 输出 "Hello, I'm Jane Doe"

在这个例子中,greet 函数接受一个遵循 Person 接口的对象作为参数,并调用其 sayHello 方法。虽然 user 不是一个类实例,但它遵循了 Person 接口的形状,因此可以被传递给 greet 函数。

八、相关链接

  1. TypeScript中文网
  2. TypeScript下载
  3. TypeScript文档
  4. 「TypeScript系列」TypeScript 简介及基础语法
  5. 「TypeScript系列」TypeScript 基础类型
  6. 「TypeScript系列」TypeScript 变量声明
  7. 「TypeScript系列」TypeScript 运算符
  8. 「TypeScript系列」TypeScript 条件语句
  9. 「TypeScript系列」TypeScript 循环
  10. 「TypeScript系列」TypeScript 函数
  11. 「TypeScript系列」TypeScript Number
  12. 「TypeScript系列」TypeScript String
  13. 「TypeScript系列」TypeScript Array(数组)
  14. 「TypeScript系列」TypeScript Map 对象
  15. 「TypeScript系列」TypeScript 元组
  16. 「TypeScript系列」TypeScript 联合类型/联合类型数组
  17. 「TypeScript系列」TypeScript 接口/接口继承

标签:TypeScript,console,string,继承,系列,方法,class,log
From: https://blog.csdn.net/xuaner8786/article/details/139174526

相关文章

  • 三菱works3库系列2-密码等级输入修改FB(上)
    1处理密码等级和修改等级(建议修改等级权限最高)2根据密码等级,比较密码输入,此例中D1000~D1010预设了5组密码,输入正确后会置位5个标志位M1000~M1004,用来做权限和隐藏之类,密码输入正确或者错误都会出来对应标志位用来提示,并清空输入的密码3注销,会复位M1000~M1004,并清空密码......
  • Living-Dream 系列笔记 第58期
    T1第一问开桶统计即可。第二问我们采用双指针,不断地移动\(r\)直到包下含有最多单词数的区间,再移动\(l\)使答案更优并不断更新答案即可。具体有一些细节见代码。时间复杂度\(O(n\logn)\)。可以把代码中的两个map换成数组存hashvalue,时间可以降至\(O(n)\),但是我懒了......
  • 深入理解C++智能指针系列(一)
    引言都知道C/C++的最难的就是需要程序员自己管理内存,往往会因为一个简单的逻辑错误导致内存管理异常。通常内存管理过程中会遇到以下问题:内存泄漏:当开发者忘记释放已分配的内存时,就会发生内存泄漏。这种情况在大型项目中非常常见,项目中存在大量动态内存操作时,很容易遗漏......
  • TypeScript 学习笔记(十一):TypeScript 与微服务架构的结合应用
    TypeScript学习笔记(十一):TypeScript与微服务架构的结合应用1.引言在前几篇学习笔记中,我们探讨了TypeScript的基础知识、前后端框架的结合应用、测试与调试技巧、数据库以及GraphQL的结合应用。本篇将重点介绍TypeScript与微服务架构的结合应用,包括如何使用TypeSc......
  • TypeScript 学习笔记(十二):TypeScript 与 DevOps 的结合应用
    TypeScript学习笔记(十二):TypeScript与DevOps的结合应用1.引言在前几篇学习笔记中,我们探讨了TypeScript的基础知识、前后端框架的结合应用、测试与调试技巧、数据库、GraphQL以及微服务架构的结合应用。本篇将重点介绍TypeScript与DevOps的结合应用,包括如何在D......
  • python系列:Python3 XML处理模块详解
    Python3XML处理模块详解Python3XML处理模块详解一:XML文件格式二:ElementTree解析XML文件Element常用属性如下:1、tag2、attrib3、text4、childelements三:Element之查找四:Element之修改五:Element之删除六:Element之增加七:Element之排序Python3XML处理模块详解x......
  • 运维系列&go系列:cannot find package “xxx“ in any of的通用解决方案
    cannotfindpackage“xxx“inanyof的通用解决方案目录问题背景解决通用解决方案这个问题遇到频率还是比较高,这次总结出来,希望能让更多的人脱离苦海!如有帮助,欢迎留下足迹哦!问题背景作者的问题:提示找不到的是工程内部自定义的包名今天出了个奇怪的事情,编译......
  • 【Docker系列】 Docker容器具体信息查询
    ......
  • 【达梦系列】IFUN_DATETIME_MODE 导致【无效的客户端版本】
    问题描述在项目开发时,应用程序连接达梦数据库报错:无效的客户端版本。这个问题在没有调整达梦数据参数之前是正常的,调整之后就不对了,但是又不清楚到底是哪个参数的问题。因为调整达梦参数时,用了一个达梦的参数调优脚本(之前能在官网找到,现在找不到了)解决思路根据这个报错,感......
  • SpringBoot系列---【】
    1.报错信息18:11:03.812[main]ERRORorg.springframework.boot.SpringApplication-Applicationrunfailedorg.yaml.snakeyaml.error.YAMLException:java.nio.charset.MalformedInputException:Inputlength=1 atorg.yaml.snakeyaml.reader.StreamReader.update(Strea......