首页 > 技术文章 > TS学习笔记--类

xujinglog 2021-04-08 15:19 原文

// 类可以理解为末班,通过模板实例化对象
// 面向对象的编程思想
(()=>{
    class Person{
        // 定义属性
        name:string
        age:number
        gender:string
        // 定义构造函数,为了将来实例化对象的时候,直接对属性的值进行初始化
        constructor(name:string='默认',age:number=0,gender:string='默认'){
            // 更新对象中的属性数据
            this.name = name
            this.age = age
            this.gender = gender
        }
        // 定义实例方法
        sayHi(str:string){
            console.log(`大家好我是${this.name}`,str);
        }
    }

    // ts中使用类,实例化对象,可以直接进行初始化操作
    const person = new Person('黄',11,'11') 
    person.sayHi('我也好')
})()

继承

// 继承类与类之间的关系
// 继承后类与类之间的叫法
// A继承B,A是B的子类,B类是基类
// 子类 ----> 派生类
// 基类 ----> 超类(父类)
// 一旦发生了继承的关系,就出现了父子类的叫法
(()=>{
    // 定义一个类
    class Person{
        // 定义属性
        name:string // 名字
        age:number
        gender:string
        // 定义构造函数
        constructor(name:string,age:number,gender:string){
            // 更新对象中的属性数据
            this.name = name
            this.age = age
            this.gender = gender
        }
        // 定义实例方法
        sayHi(str:string){
            console.log(`大家好我是${this.name}`,str);
        }
    }
    
    // 定义一个类继承Person
    class Student extends Person{
        constructor(name:string,age:number,gender:string){
            // 调用父类中的构造函数
            super(name,age,gender)
        }
 
        // 可以调用父类中的方法
        sayHi(){
            console.log('子类');
            super.sayHi('你在干嘛')
        }
    }
    const stu = new Student('黄',1,'1')
    stu.sayHi()
    
    // 类和类之间如果要有继承关系,需要使用extends 关键字
    // 子类中可以调用父类中的构造函数,使用的是super关键字(包括父类中的实例方法)
    // 子类可以重写父类的实例方法
})()

多态

// 多态:父类型的引用指向了子类型的对象,不同类型的对象针对相同方法,产生了不同的行为
(()=>{
    // 定义一个父类
    class Animal{
        // 定义一个属性
        name:string
        constructor(name:string){
            this.name = name
        }
        // 实例方法
        run(distance:number = 0){
            console.log(distance,this.name);
        }
    }

    // 定义一个子类
    class Dog extends Animal{
        constructor(name:string){
            super(name)
        }
        run(distance:number = 5){
            console.log(distance,this.name)
        }
    }

    // 定义一个字类
    class Pig extends Animal{
        constructor(name:string){
            super(name)
        }
        run(distance:number = 10){
            console.log(distance,this.name)
        }
    }

    const ani:Animal = new Animal('动物')
    ani.run()

    const ani1:Dog = new Dog('动物')
    ani1.run()

    const ani2:Pig = new Pig('猪')
    ani2.run()

    // 父类和子类的关系:父子关系,父类类型创建子类对象
 
    const dog1:Animal = new Dog('dog')
    dog1.run()

    const pig1:Animal = new Pig('pig')
    pig1.run()

    console.log('==============');
    
    // 该函数需要的参数是Animal类型的
    function showRun(ani:Animal){
        ani.run()
    }
    showRun(pig1)
    showRun(dog1)
})()

修饰符

// 修饰符(类中的成员的修饰符):主要是描述类中的成员可访问性
// 类中的成员都有自己的默认的访问修饰符,public
// public 代表 类中成员默认的修饰符,代表的是公共的,任何位置都可以访问
// private 代表 类中成员 是私有的,子类也无法访问
// protected修饰符,外部无法访问,子类可以访问
(()=>{
    // 定义一个类
    class Person{
        // 属性
        // private name:string
        // public name:string
        protected name:string
        // 构造函数
        public constructor(name:string){
            this.name = name
        }
        // 方法
        public eat(){
            console.log('吃',this.name);
        }
    }

    class Students extends Person{
         constructor(name:string){
            super(name)
        }
        play(){
            console.log('111',this.name);
        }
    }

    // 实例化对象
    const per = new Person('黄') 
    // 类的外部可以访问类中的属性成员
    // console.log(per.name); 
    per.eat()
    const stu = new Students('红豆')
    stu.play()
    // console.log(stu.name); 


})() 

readonly

// readonly修饰符:首先是一个关键字,对类中的属性成员进行修饰,修饰符后,该属性成员不能在外部随意修改
// 构造函数可以对只读的属性成员的数据进行修改
// 如果构造函数中没有任何的参数,类中的属性成员此时已经使用readonly进行修饰,外部也不能对属性值进行修改
// 构造函数中的参数可以使用public private protected 修饰
(()=>{
    // 1、readonly 修饰类中的成员属性操作
    // 定义一个类型
    // class Person{
    //     // name: any;
    //     // 属性
    //     readonly name:string
    //     constructor(name:string){
    //         this.name = name
    //     }
    //     sayHi(){
    //         console.log('hi',this.name);
    //         // 类中的普通方法,也不能修改readonly
    //         // person.name = '梁'  
    //     }
    // }
    // // 实例化对象
    // const person:Person = new Person('黄')
    // // 此时无法修改 name属性为readonly
    // // person.name = '梁'  
    // console.log(person);
    // console.log(person.name);
    
    // 1、readonly 修饰类中的构造函数的的参数
    class Person{
        // 构造函数中的name参数,一旦使用readonly进行修饰该参数可以叫做参数属性
        // 构造函数中的name参数,一旦使用readonly进行修饰之后,Person中就有了一个name属性成员
        // 这种方式修饰,person.name = '梁' 外部无法修改
        // constructor(readonly name:string){
        //     this.name = name
        // }

        // 构造函数中的name参数,一旦使用public进行修饰,那么Person类中就有了一个name公共属性
        // constructor(public name:string){
        //     this.name = name
        // }

        // 构造函数中的name参数,一旦使用private进行修饰,那么Person类中就有了一个name私有属性
        // constructor(private name:string){
        //     this.name = name
        // }

        // 构造函数中的name参数,一旦使用protected进行修饰,那么Person类中就有了一个name受保护属性成员,只能读
        constructor(protected name:string){
        this.name = name
    }
       
    }
    // 实例化对象
    const person:Person = new Person('黄')
    // 此时无法修改 name属性为readonly
    // person.name = '梁'  
    console.log(person);
    // console.log(person.name);
    
})()

存取器

// 存取器:让我们有效的控制对 对象 中的成员进行访问,通过getter和setter来进行操作
(()=>{
    // 在外部可以传入姓氏和名字的数据,同时使用set和get控制姓名的数据,外部也可以修改
    class Person{
        firstname:string // 姓氏
        lastName:string // 名字
        
        constructor(firstName:string,lastName:string){
            this.firstname = firstName
            this.lastName = lastName
        }

        // 读取器
        get fullName(){
            return this.firstname+'_'+ this.lastName
        }

        // 设置器
        set fullName(val){
            let names = val.split('_')
            this.firstname = names[0]
            this.lastName = names[1]
        }
    }
    const person:Person = new Person('黄','梁')
    console.log(person);
    console.log(person.fullName);
    person.fullName = '在_这'
    console.log(person.fullName);

})()

静态成员

// 静态成员:在类中通过static修饰的属性或者方法,那么就是静态的属性及静态的方法,称之为静态成员
// 静态成员在使用的时候是通过类名.的这种语法来调用
(()=>{
    class Person{
        static name1:string = '梁'
        // 构造函数
        
        // static constructor(){
        //     // 此时this是实例dioxide,name1是静态属性,不能通过实例对象直接调用静态属性来使用
        //     // this.name1 = name
        // }
        
        constructor(){
            // 此时this是实例dioxide,name1是静态属性,不能通过实例对象直接调用静态属性来使用
            // this.name1 = name
        }
        // 静态方法
        static eat(){
            console.log('吃');
        }
    }

    // const person:Person = new Person() 
    // 通过实例对象调用属性
    // console.log(person.name1);
    // 通过实例对象调用方法
    // person.eat()
    // 通过类名.的这种语法来调用静态属性
    console.log(Person.name1);
    // 通过类名.的这种语法来设置静态属性
    Person.name1 = "赋值成功"
    console.log(Person.name1);
    // 通过类名.的这种语法来调用静态方法
    Person.eat()

})()

抽象类

// 抽象类:包含抽象方法(抽象方法一般没有任何的具体内容的实现),也包含实例方法,抽象类是不能被实例化,为了让子类进行实例化及实现内部的方法
// 抽象类的目的或者作用都是为子类服务
(()=>{
    // 定义一个类
    abstract class Animal {
        // abstract name:string = '小图'
        // 抽象方法
        abstract eat()
        // 抽象方法不能有具体实现
        // abstract eat(){
        //     console.log('趴着吃,挑着吃');
        // }

        // 实例方法
        run(){
            console.log('都跑了');
        } 
    }  
    
    // 定义一个子类(派生类)Dog
    class Dog extends Animal{
        name:string='小黄'
        // 重新的实现抽象
        eat(){
            console.log('子类挑着吃');
        }
    }
    // 不能实例化抽象类的对象
    // const ani:Animal = new Animal()

    const dog:Dog = new Dog()
    dog.eat()
    dog.run()
    console.log(dog.name);
    
})()

推荐阅读