• ts随记:面向对象、泛型


    啊啊啊啊啊真的会谢!和后端拿一个数据,问半天为什么要这个数据
    言归正传!我!终于看懂了三年前没有学懂的面向对象了
    ts是个好东西啊兄弟们

    类:

    • 实例属性:直接定义,需要通过实例进行访问的
    • 类属性(静态属性):static 直接通过类访问
    • 只读属性:readonly 不能改
    • public(默认) :属性可以在任意位置访问(修改)
      private: 私有属性,只能在类内部进行访问修改,不被子类访问
      protect: 保护属性,只能在当前类和子类中使用
    class Person{
        // 直接定义的为实例属性,要通过实例进行访问
        name: string = '孙悟空';
        // 在属性前使用static可以定义类属性(静态属性)
        static age: number = 18;
        // readonly:只读属性,不可修改
        readonly gender: number = 0;
        // 定义方法(使用static可以定义类方法)
        sayHello(){
            console.log("say hello");
        }
    }
    
    const per = new Person();
    console.log(per);//Person {name: '孙悟空'}
    console.log(Person.age);//18
    // per.gender = 1;//报错
    
    // 方法
    per.sayHello()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    构造函数:可以实现动态赋值

    • constructor:在创建对象时被调用
    • this:指向构建的对象的属性(class的属性)
    class Dog{
        name = '旺财';
        age = 3;
        bark(){
            alert('wwww')
        }
        // 构造函数: 在创建对象时被调用
        constructor(name: string, age: number){
            // this指向构建的对象中的属性
            this.name = name,
            this.age = age
        }
    }
    const dog = new Dog("小黄", 1);
    const dog1 = new Dog("小花", 2);
    const dog2 = new Dog("大黄", 18);
    console.log(dog);
    console.log(dog1);
    console.log(dog2);
    //Dog {name: '小黄', age: 1}
    //Dog {name: '小花', age: 2}
    //Dog {name: '大黄', age: 18}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    继承: 将几个拥有共同属性,共同方法(功能)的类合并在一起,只写一次,再进行个性化修改

    • 子类中写父类的方法名的方法,叫做重写
    • super为父类对象,可以获取父类的属性方法等
    • 当子类有新增的属性,需要用到constructor进行构造,此时需要引入父类的属性
    (function(){
        class Animal{
            name: string | undefined;
            age: number | undefined;
    
            constructor(name: string, age: number){
                this.name = name;
                this.age = age;
            }
    
            sayHello(){
                console.log('父类:动物在叫');
            }
        }
        // extends: 继承
        // 子类(Dog)继承父类(Animal)
        // 子类拥有父类所有的方法和属性
        // 作用:将多个类中共有的代码统一写在父类中
        //super为父类对象
        class Dog extends Animal{
            gender: number | undefined;
            constructor(name: string, age: number, gender: number){
                super(name, age);
                this.gender = gender;
            }
            run(){//属于当前子类自己的方法
                console.log(`${this.name}在跑`);
            }
            sayHello() {//重写父类方法
                console.log('子类:狗子叫');
                super.sayHello();
            }
        }
    
        const dog = new Dog('狗子', 5, 0)
        console.log(dog);
        dog.sayHello();
        dog.run();
    })()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    抽象类:父类不能被直接使用,是一个抽象化的存在,没有实质性的功能,只能被继承

    • abstract :不能用于创建实例,只能被继承
    • 抽象类中可以定义抽象方法,继承者必须重写该方法
    (function(){
        // abstract :抽象类
        // 不能用于创建对象(new CLASS())
        // 只是用来被继承(只能当爸爸)
        abstract class Animal{
            name: string | undefined;
            age: number | undefined;
    
            constructor(name: string, age: number){
                this.name = name;
                this.age = age;
            }
            // 可以添加抽象方法 ,同样只能被重写,不能直接被调用
            // 只能被定义在抽象类中
            // 继承类者必须重写改方法
            abstract sayHello():void;
        }
        class Dog extends Animal{
            sayHello() {
                console.log('子类:狗子叫');
            }
        }
    
        const dog = new Dog('狗子', 5)
        console.log(dog);
        dog.sayHello();
    })()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    接口:用来定义一个类的规范(模板),是一种规范化的存在

    • 可以多次定义,最终进行合并(???有点怪,感觉有坑)
    • 里面的所有属性没有实际的值(函数==抽象函数)
    (function(){
        type myType = {
            name: string,
            age: number
        }
    
        // 接口:用来定义一个类的规范(模板)
        // 可以多次定义,最终进行合并(???有点怪,感觉有坑)
        interface myInterface{
            name: string,
            age: number
        }
        interface myInterface{
            gender: number
        }
        const obj: myInterface = {
            name: '11',
            age: 88,
            gender: 0
        }
        // 接口可以限制类的结构
        // 里面的所有属性没有实际的值(函数==抽象函数)
        interface MyInter{
            name: string;
            sayHello():void;
        }
        class MyClass implements MyInter{
            name: string;
            constructor(name: string){
                this.name = name;
            }
            sayHello(){
                console.log("大家好");
                
            }
        }
    })()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    属性封装:可以做到拦截修改,提高安全性

    • ts中自己封装了getter和setter的方法,在需要进行修改拦截(年龄问题)的情况下可以进行使用
    (function(){
        class Person{
            // public(默认) :属性可以在任意位置访问(修改)
            // private: 私有属性,只能在类内部进行访问修改,可以做到拦截修改(set,get)
            // - 私有熟悉不被子类访问
            // protect: 保护属性,只能在当前类和子类中使用
            private _name: string;
            private _age: number;
            constructor(name:string, age: number){
                this._name= name;
                this._age = age;
            }
            get age(){
                return this._age;
            }
            //=================原理
            // getAge(){
            //     return this._age;
            // }
            set age(value: number){
                if(value < 0 || value > 200){
                    throw new Error("age不合法");
                }
                this._age = value
            }
            //==================原理
            // setAge(value:number){
            //     if(value < 0 || value > 200){
            //         throw new Error("age不合法");
            //     }
            //     this._age = value;
            // }
        }
    
        const per = new Person('孙悟空', 18);
        per.age = 100
        console.log(per.age);//100
    })()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    泛型:对不确定类型的参数进行变量定义,调用时再指定

    // 定义函数/类时,遇到类型不明确时可以使用泛型
    // T为类型的变量,调用时才赋值
    function fn<T>(a:T): T{
        return a;
    }
    console.log(fn(10));//不指定泛型,TS自动对类型进行推断
    console.log(fn<string>('hello'));//指定泛型
    
    function fn2<T,K>(a:T, b:K):T{
        console.log(b);
        return a;
    }
    interface Inter{
        length: number;
    }
    // T 要实现Inter接口(拥有length属性:字符串、obj.length)
    function fn3<T extends Inter>(a: T): number{
        return a.length;
    }
    fn3('123');
    fn3({length: 7})
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    我第一次接触ts,因为不理解ts使用的意义比如说接口,结果全程把ts当js写
    其实对于ts的意义,在学习理解了面向对象的思想之后,倒是有点清楚了。
    到最后老师说了,这个东西并不是说一定要用,但是他是一种规范,一种思想。
    虽然有些配置和操作确实比起js来说复杂不少,但是不得不说,统一开发规范可见地会大大地有利于后期维护以及多人的合作开发
    如果你还是有点不理解ts到底用来干嘛,建议花点时间看看这几个视频

  • 相关阅读:
    照片全屏水印轻松去除,让你的照片焕然一新
    为了保证openGauss的正确安装,请首先对主机环境进行配置
    工程师必备Linux最新命令大全
    ClickHouse(03)ClickHouse怎么安装和部署
    提升编码幸福感的秘密「GitHub 热点速览」
    前端练习--W3C导航条
    武汉新时标文化传媒有限公司新版抖店正式上线
    C++-继承-单继承-多继承-虚函数-内存结构分析-类分析-无源码-逆向分析(三)
    统计元音字母个数
    element-plus 表格-自定义样式实现
  • 原文地址:https://blog.csdn.net/weixin_46221198/article/details/125611576