VueBloghyhero6

TS 类

2024-07-18 / 2024-07-18 / 44次浏览
严格说,在 react 范围内,TS类并不多见,严格来说,是TS 自己单独使用的时候才强调类。


类的几个使用方向,抽象类,类继承,类的公有私有属性,静态属性,以及抽象类。
类继承

class Animal {
    move(steps: number = 0) {
        console.log(`这个动物移动了多少 ${steps}`)
    }
}
动物可以移动,输出动物走了多少步。

class Dog extend Animal {
    wang() {
        console.log('狗子会汪汪叫')
    }
}

让狗继承动物属性,然后狗可以走,可以wang 叫。
const dog = new Dog();
dog.wang();
dog.move();

直白的例子,狗子走和叫
复合版增加super,上面的类一个被称为基类,一个被称为子类,子类可以复写基类的方法
如果没有显示的调用构造函数 constructor, 系统会默认自己追加,但是如果调用了构造函数,那么super就得用啥

class Dog extend Animal {
    move(steps: number = 20) {
       super.move(steps)
    }
    wang() {
        console.log('狗子会汪汪叫')
    }
}

这个例子用 move 复写了基类的move, 这个例子说明你基类的 super 一定是有用的,所以才会有回调。上面那个就没有constructor。
但是更完整的例子是,子类有自己得变量要定义,然后还有要继承的基类变量,那么 constructor 这时候肯定会被声明出来。

class Animal {
    name: string;
    constructor(name: string) {
        this.name = name;
    }
    move(steps: number = 0) {
        console.log(`${this.name} 移动了多少 ${steps}`);
    }
}

class Dog extend Animal {
    anotherName: string;
    constructor(name: string, anotherName: string) {
        super(name);
        this.anotherName = anotherName;
    }
    move(steps: number = 20) {
       super.move(steps)
    }
    wang() {
        console.log('狗子会汪汪叫')
    }
}

const dog = new Dog("小黑", "牧羊犬");
dog.move(); // 输出:牧羊犬 狗子移动了:小黑 移动了多少 20
dog.wang(); // 输出:小黑 会汪汪叫

大概应该是讲明白了, 上面主要是constructor 和 super
下一条默认 public, 类似就是上面的 name 什么 都要加上 public

关于 private, 私有属性该类型只能自己访问

class Animal {
    private name: string;

    constructor(name: string) {
        this.name = name;
    }

    move(steps: number = 0) {
        console.log(`${this.name} 移动了 ${steps} 步`);
    }
}

const animal = new Animal("小动物");
animal.move(10); // 输出:小动物 移动了 10 步

// 尝试访问私有属性
console.log(animal.name); // 报错:属性“name”为私有属性,只能在类“Animal”中访问

静态属性static 实例可访问, 派生属性 protect, 子类可以访问,但是实例无法访问, readonly 属性只读
这里只举例一个 static 因为真的可能会用到
class Grid {
    static origin = {x: 0, y: 0};
    calculateDistanceFromOrigin(point: {x: number; y: number;}) {
        let xDist = (point.x - Grid.origin.x);
        let yDist = (point.y - Grid.origin.y);
        return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale;
    }
    constructor (public scale: number) { }
}

let grid1 = new Grid(1.0);  // 1x scale
let grid2 = new Grid(5.0);  // 5x scale

console.log(grid1.calculateDistanceFromOrigin({x: 10, y: 10}));
console.log(grid2.calculateDistanceFromOrigin({x: 10, y: 10}));

console.log(grid1.origin); // 输出 { x: 0, y: 0 }
console.log(grid2.origin); // 输出 { x: 0, y: 0 }

其实还是public 和 private 一个公有一个私有这俩个使用的多些。
比较进阶的
高阶抽象类给基类做派生,无法被实例化 关键字是 abstract 用于定义抽象类和在抽象类内部定义抽象方法

abstract class Animal {
    abstract makeSound(): void;
    move(): void {
        console.log('roaming the earch...');
    }   
}

class Dog extends Animal {
    makeSound(): void {
        console.log('汪汪汪!'); // 实现抽象方法
    }
}

const dog = new Dog();
dog.makeSound(); // 输出:汪汪汪!
dog.move();      // 输出:roaming the earth...

抽象类决定了自己必须实现自己得抽象方法,不然它自己也只能是一个抽象类,作用的话就是模板作用。