class 简介
typescript 全面支持es2015中引入的class关键字,并为其添加了类型注解,和其它语法(比如,可见性修饰符等),
class 基本使用,如下
tips
1. 根据ts中的类型推论,可以知道Person的实例对象p的类型是Person
2. ts中的class,不仅提供了class的语法功能,也作为一种类型存在
class 初始化
ts中class初始化有两种,一种指定类型,一种直接赋初始值
//给类成员指定类型class Person {name: stringage: number}//直接赋初始值,让类成员类型推论,省略类型注解class Animal {type = '小狗'age = 18//age:number=18 ??? 这里当然能这样写,但是能使用类型推论,为什么还要手写呢?}
总结: 在ts中创建类和js中一样,都使用class关键字来创建,同样的,创建实例对象都通过new关键字实现,
添加类成员,有两种方法
- 给类成员指定类型
- 省略掉类型注解,直接给类赋值,让成员通过类型推论确认类型
class 构造函数 constructor
构造函数(Constructor)是一种特殊的方法,用于在创建新对象时初始化类。在TypeScript(和JavaScript)中,构造函数是类的默认方法,当你创建一个类的新实例时,它会被自动调用。
构造函数通常以类的名称命名,并且没有返回类型注释。在TypeScript(和ES6 JavaScript)中,构造函数可以通过使用 constructor 关键字来定义
示例如下
class Person {name: stringage: numberconstructor(name: string, age: number) {this.name = namethis.age = age}
}
- 成员初始化(比如,age:number)后才可以通过this.age来访问实例成员
- 需要为构造函数指定类型注解,否则会被隐式推断为any;构造函数不需要返回值类型
class 实例方法
在TypeScript(及其基础语言JavaScript)中,类的实例方法是定义在类中的方法,它们被用于操作类的实例。这些方法可以使用this关键字引用类的实例。
实例方法是在类的定义中定义的方法,而不是在类的实例上直接定义的方法。这意味着每个类的实例都有自己的实例方法副本。
class Person {name: stringage: number//实例方法的类型注解(参数和返回值)与函数用法相同sayHello() {// 实例方法通过this访问成员变量console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`)}constructor(name: string, age: number) {this.name = namethis.age = age}
}
tips 实例方法的类型注解(参数和返回值)与函数用法相同
每个实例都拥有实例方法的副本
如下,使用new关键字,创建两个实例对象,他们都能调用自己的sayHello方法
class 类继承 extends 继承父类
在TypeScript(及其基础语言JavaScript)中,类继承是一种实现代码重用和抽象的重要技术。通过类继承,您可以创建一个新类(子类),该类从已存在的类(父类)继承属性和方法。这样,子类就可以重用父类的代码,同时还可以添加或覆盖父类的特性以满足特定的需求。
tips js中只有extends ,而implements是ts提供的
实例如下
如上实例,当dog类继承了anilmal类时,dog类就有了anilmal类的所有方法,
注意,如果类继承时,父类有构造函数时,需要使用super关键字来调用父类的方法
上面super关键字调用父类的构造函数时没有传参是因为父类构造函数本身没有形参
class 类继承 implements (实现接口)
在TypeScript中,一个类可以实现一个接口。这意味着类需要定义接口中所有的方法和属性。这种技术在JavaScript中也被广泛使用,因为它允许开发者创建具有特定行为和属性的对象。
示例如下
// 定义一个Animal接口,包含两个属性:name和greet
interface Animal { // name是一个字符串类型的属性 name: string; // greet是一个没有返回值(void)的方法 greet(): void;
} // 定义一个Dog类,这个类实现了Animal接口
class Dog implements Animal { // name是Dog类的属性,与Animal接口中的name对应 name: string; // 构造函数,用于创建Dog类的实例并初始化name属性 constructor(name: string) { this.name = name; } // greet是Dog类的方法,与Animal接口中的greet对应 greet() { // 该方法用于在控制台打印一条问候语,包含实例的name属性 console.log(`Hello, I am ${this.name}.`); }
}
- 通过implements 关键字让class 实现接口
- Dog类实现接口Animal意味着,Dog类中必须提供Animal中指定的所有方法和属性
class 成员的可见性修饰符 public/protected/private
在TypeScript中,类成员的可见性修饰符用于控制类成员的访问权限。以下是TypeScript中可用的可见性修饰符:
- public:成员是公共的,可以在任何地方访问。这是默认的可见性修饰符。
- protected:成员是受保护的,只能在类本身和它的子类中访问。
- private:成员是私有的,只能在类本身中访问。
public 表示公有的,公开的,公有成员可以被任何地方访问,默认可见性
// 定义一个名为 Animal 的类
class Animal { // 定义一个公共属性 name,类型为字符串 // 这里 public 是默认修饰符,可以省略不写 public name: string; // 定义一个构造函数,接收一个字符串参数 name constructor(name: string) { // 将传入的参数 name 赋值给属性 name this.name = name; }
} // 定义一个名为 Dog 的类,它继承自 Animal 类
class Dog extends Animal { // 定义一个公共属性 species,类型为字符串 public species: string; // 定义一个构造函数,接收两个参数:name 和 species constructor(name: string, species: string) { // 使用 super 关键字调用父类 Animal 的构造函数,传入参数 name super(name); // 将传入的参数 species 赋值给属性 species this.species = species; }
} // 创建一个新的 Animal 实例,并传入参数 "xiaohei"
let animal = new Animal("xiaohei"); // 创建一个新的 Dog 实例,并传入参数 "xiaobai" 和 "dog"
let dog = new Dog("xiaobai", "dog"); // 打印 animal 实例的 name 属性值,输出 "xiaohei"
console.log(animal.name); // 打印 dog 实例的 name 属性值,输出 "xiaobai"
console.log(dog.name);
可以看到,Animal 被public修饰符修饰的species属性成员,可以在任何地方被访问,
protected 受保护的,仅对其声明所在的类和子类中(非实例对象)可见
如上,可以看见,当我将父类Anilmal的属性name 使用protected 修饰符修饰后,实例对象就不能访问该属性了
tips : 当然子类可以通过实例方法来修改protected 修饰符修饰的属性,因为那是在内部通过this修改
- 在类属性或方法前面添加protected关键字,来修饰该属性或,方法是受保护的
- 在子类的方法内部可以通过this来访问父类中受保护的成员,但是对实例不可见!!!
private: 表示私有的,只在当前类中可见,对实例对象以及子类也是不可见的。
tips
- 在类属性或方法前面添加 private 关键字,来修饰该属性或方法是私有的
- 私有的属性或方法只在当前类中可见,对子类和实例对象也都是不可见的!
class 总结
- 成员初始化(比如,age:number)后才可以通过this.age来访问实例成员
- 需要为构造函数指定类型注解,否则会被隐式推断为any;构造函数不需要返回值类型