您现在的位置是:首页 >技术杂谈 >详细版易学版TypeScript - 类网站首页技术杂谈

详细版易学版TypeScript - 类

EchoLiner 2024-06-14 17:20:26
简介详细版易学版TypeScript - 类

一、类 - 类的属性和方法

class MyPreson {
    // 类的属性
    // 属性需要在类里先定义并确定类型,才可以在constructor里面用this访问
    name: string
    age: number
    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }
    // 类的方法
    sendStr(str: string) {
        console.log("hi,", str); // hi, pinia
    }
}

const per = new MyPreson("vite", 123);
per.sendStr("pinia");

二、类 - 类的继承

Father父类

class Father {
    name: string
    age: number
    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }
    changeName(str: string) {
        console.log("hello,", str);
    }
}

Son1、Son2子类

1、继承父类的方式一

继承父类属性:调用父类的构造函数,使用super()

继承父类方法:如果子类没有changeName()方法,在子类的实例对象调用changeName()方法,那就是继承父类的changeName()方法

class Son1 extends Father {
    constructor(name: string, age: number) {
        // 调用父类的构造函数,使用super
        super(name, age);
    }
}
let son1 = new Son1("son1", 12);
// 继承父类的方式一
// 子类没有changeName()方法,下面的代码是继承父类的changeName()方法
son1.changeName("son1->直接继承父类的方法"); // hello, son1->直接继承父类的方法

2、继承父类的方式二

继承父类方法:

如果子类有changeName()方法,在子类的实例对象调用changeName()方法,那就是调用子类自己的changeName()方法。

那么继承父类的方法可以用super.changeName()

class Son2 extends Father {
    constructor(name: string, age: number) {
        super(name, age);
    }
    // 重写父类的方法
    changeName() {
        console.log("I am son2"); // I am son2
        // 继承父类的方式二
        // 调用父类的方法,使用super
        super.changeName("son2->使用super继承父类的方法"); // hello, son2->使用super继承父类的方法
    }
}

let son2 = new Son2("son2", 12);
// 假如子类有changeName()方法,下面的代码是调用子类自己的changeName()方法
son2.changeName();

三、类 - 存取器

帮助我们控制对象成员的访问

1、设置存取器方式一

class Name1 {
    firstName: string
    lastName: string
    constructor(firstName: string, lastName: string) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
    // 设置存取器
    // 存取器的 get set 都是属性,不是方法,只不过这两个属性不是直接定义在类的对象上面
    // 其实就是对象上有这2个属性,但不是通过constructor构造器创建的,而是通过存取器创建的
    // 读取器:用来读取数据,控制对属性的访问
    get fullName() {
        // 这里返回了固定值,执行set后,读取到的永远是“张~月”
        return `张~月`;
    }
    // 设置器:设置数据
    set fullName(value) {
        const arr = value.split('~');
        this.firstName = arr[0];
        this.lastName = arr[1];
    }
}
const myName1 = new Name1("李", "明");
console.log("set前 myName1-->", myName1);
// 访问myName的fullName
console.log("set前 myName1.fullName-->", myName1.fullName);
// 设置myName的fullName
myName1.fullName = "刘~敏";
console.log("set后 myName1-->", myName1);
console.log("set后 myName1.fullName-->", myName1.fullName);

console.log('*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*');

2、设置存取器方式二

class Name2 {
    firstName: string
    lastName: string
    constructor(firstName: string, lastName: string) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
    get fullName() {
        // 这里返回了动态数据,执行set后,读取到的就是set进去的数据
        return `${this.firstName}~${this.lastName}`;
    }
    set fullName(value) {
        const arr = value.split('~');
        this.firstName = arr[0];
        this.lastName = arr[1];
    }
}
const myName2 = new Name2("李", "明");
console.log("set前 myName2-->", myName2);
console.log("set前 myName2.fullName-->", myName2.fullName);
myName2.fullName = "刘~敏";
console.log("set后 myName2-->", myName2);
console.log("set后 myName2.fullName-->", myName2.fullName);

查看打印结果:

四、类 - 静态成员

类的静态属性和静态方法

也就是只属于类自己的属性和方法,只可以通过类自己去调用,不可以通过实例对象去调用

class StaticName {
    static myName: string
    constructor(myName: string) {
        StaticName.myName = myName;
    }
    static sayHi() {
        return "hi";
    }
}

const testName = new StaticName("test");
console.log("testName.myName-->", testName.myName); // 报错,实例对象❌不可以调用类的静态属性
console.log("testName.sayHi-->", testName.sayHi()); // 报错,实例对象❌不可以调用类的静态方法

console.log("StaticName.myName-->", StaticName.myName); // 类可以调用自己的静态属性
console.log("StaticName.sayHi-->", StaticName.sayHi()); // 类可以调用自己的静态方法

五、类 - 修饰符

1、公有修饰符 public:类里面、子类、实例对象都能访问

2、私有修饰符 private:只能在类里面访问,子类、实例对象都不能访问

3、受保护的修饰符 protected: 只能在类里面及其子类中访问,实例对象不能访问

class MyFather {
    public test1: string // 公有属性
    private test2: string // 私有属性
    protected test3: string // 受保护的属性
    constructor(test1: string, test2: string, test3: string) {
        this.test1 = test1;
        this.test2 = test2;
        this.test3 = test3;
    }
    public myMethods1() { // 公有方法
        return this.test1; // 类里面可以访问自己的公有属性
    }
    private myMethods2() { // 私有方法
        return this.test2; // 类里面可以访问自己的私有属性
    }
    protected myMethods3() { // 受保护的方法
        return this.test2; // 类里面可以访问自己的受保护的属性
    }
}
const myFather1 = new MyFather("father hi", "father vite", "father pinia");
console.log(myFather1.test1); // 实例对象可以访问类的公有属性
console.log(myFather1.test2); // 报错,实例对象❌不可以访问类的私有属性
console.log(myFather1.test3); // 报错,实例对象❌不可以访问类的受保护的属性

class MySon extends MyFather {
    constructor(test1: string, test2: string, test3: string) {
        super(test1, test2, test3);
    }
    changeName1() {
        super.myMethods1(); // 子类可以访问父类的公有方法
    }
    changeName2() {
        super.myMethods2(); // 报错,子类❌不可以访问父类的私有方法
    }
    changeName3() {
        super.myMethods3(); // 子类可以访问父类的受保护的方法
        console.log(this.test1); // 子类可以访问父类的公有属性
        console.log(this.test2); // 报错,子类❌不可以访问父类的私有属性
        console.log(this.test3); // 子类可以访问父类的受保护的属性
    }
}

4、只读修饰符 readonly

// 只有在类的constructor构造函数里面可以修改
// 其他任何地方都不可以修改(包括类自己的方法内部、子类、实例对象都不可以修改)
class ReadOnly {
    readonly x: string
    constructor(x: string) {
        this.x = x;
    }
    readOnly() {
        this.x = "hi" // 报错,类内部❌不可以修改只读属性
    }
}
const readOnly = new ReadOnly("hi");
readOnly.x = "element plus"; // 报错,实例对象都❌不可以修改只读属性

5、属性修饰符的另一种书写方式

class Other {
    // 创建并初始化constructor的参数,有以下2种方式
    // 方式一:普通写法
    /*
    readonly x:number
     constructor(x:number){
         this.x = x;
     }
    */
    // 方式二:readonly直接定义在参数上
    constructor(readonly x:number){
    }
    // public、private、protected修饰符同理,也可以直接定义在参数上,这里省略举例
}
console.log(new Other(456));
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。