Appearance
认识类的使用
ts
class Person {
constructor(name: string) {
this.name = name;
}
}
const p1 = new Person();
const p2 = new Person();
如果你的类中有成员变量, 必须要在类里面进行声明成员属性
ts
class Person {
name: string;
age: number;
// 初始化不为空 可以不 constructor
name!: string;
age!: number;
// ||
name = "";
age = 0;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
const p1 = new Person();
const p2 = new Person();
类的成员修饰符
修饰符
public 修饰符 任何地方可见 默认属性就是 public private 私有属性 方法 只有在类的内部才可以访问 protected 修饰符仅在类自身及子类中可见 受保护的属性和方法
ts
class Person {
public name: string;
protected age: number;
constructor(name: string, age: number) {
this.name = name;
this.number = number;
}
private eating() {}
}
class Student extends Person {
constructor(name: string, number: number) {
super(name, number);
}
study() {
console.log(this.age);
}
}
readonly
ts
class Person {
readonly name: string
constructor(name: string) {
...
}
}
const p = new Person('erer')
p.name = 'adny' // error readonly 不可写
getter 和 setter
正常情况下,如果我们定义了 private 私有属性外界是不可以访问这个变量的,但是如果在某些特殊情况我们想要去访问 private 私有变量 那么我们可以使用 setter 和 getter
ts
class Person {
private _name: string;
constructor(name: string) {
this._name = name;
}
set name(newValue: string) {
this._name = newValue;
}
get name(): string {
return this._name;
}
}
const p = new Person("adny");
我们可以对值进行拦截 类似 proxy 和 defineProperty
类的参数属性使用
正常我们定义一个普通的类的参数 我们首先需要声明成员变量 然后给 this 赋值
ts
class Person {
name: string;
age: number;
height: number;
constructor(name: string, age: number, height: number) {
this.name = name;
this.age = age;
this.height = height;
}
}
class Person {
constructor(public name: string, public age: number, public height: number);
}
两段代码 一个意思 语法糖
抽象类
我们知道 继承是多态使用的前提
在定义许多通用的调用接口时,我们通常会让调用者传入父类,通过多态来实现更加灵活的调用方式
抽象类
如果需要计算不同类的情况下
ts
class Rectangle {
constructor(public width: number, public height: number) {}
}
class Circle {
constructor(public radius: number) {}
}
function calcArea(shape: Circle | Rectangle) {}
这种情况下 如果又需要添加一个类 我们又需要在 calcArea
中 继续添加类型,那么可以使用继承的方法
ts
abstract class Shape {
abstract getArea()
}
class Rectangle extends Shape {
...
}
class Circle extends Shape {
}
function calcArea(shape: Shape) {}
在 shape 中定义方法,不定义实现体 这样我们就可以使用 shape 中的 getArea 面向对象的过程 抽象类不能实例化
鸭子类型
在 typescript 中只要有行为 就算类型匹配成功
typescript 在对于类型检测的时候使用鸭子类型
鸭子类型
如果一只鸟,走起路来像鸭子,游起来像鸭子,看起来像鸭子,那么可以认为他就是一只鸭子
鸭子类型:只关心属性和行为,不关心具体是不是对应的类型
ts
class Person {
constructor(public name: string);
}
class Dog {
constructor(public name: string);
}
function print(p: Person) {}
print(new Dog("erkelost"));
类具有的类型特性
WARNING
类的作用 类可以创建对应的实例对象 类本身可以作为这个实例的类型 类也可以当成一个有构造签名的函数
ts
const name: string = "aaa";
const p: Person = new Person();
// 可以直接传递一个类
function factory(ctor: new () => void) {}
接口的类实现过程
定义接口,我们一般都是作为类型使用的,但是在类中,提供了另外的一种功能
ts
interface IKun {
name: string;
age: number;
play: () => void;
}
const play: IKun = {
name: 'erkelost',
age: 9999,
play() {}
};
// 这是正常定义接口
// 在类中定义接口
class Person implements IKun {
constructor(public name: string, public age: number){}
play() {
}
}
const a = new Person()
console.log(a.name)
console.log(a.age)