TypeScript篇(二) - 面向对象

135 阅读4分钟

简单事情重复做,每天进步一点点

记录自己TypeScript的学习过程。

1、使用class关键字定义

2、包含两部分(属性、方法)

示例:
class Person {
    name: string = '张三',  //实例属性
    say() { //实例方法
        console.log(“实例方法”)
    }

    static sex: string = '男', //使用static开头的为静态属性、类属性
    static skill() { //静态方法
        console.log("静态方法")
    }

    readonly age: number = 18, //使用readonly开头的为只读属性,不允许修改
    
    // TS可以在属性前添加属性的修饰符
    /*
        *   public 修饰的属性可以在任意位置访问(修改) 默认值
        *   private 私有属性,私有属性只能在类内部进行访问(修改)
        *       - 通过在类中添加方法使得私有属性可以被外部访问
        *   protected 受包含的属性,只能在当前类和当前类的子类中访问(修改)
        *
        * */
    private name1: string;
    private age1: number;

    /*
        *   属性在对象中设置的,属性可以任意的被修改,
        *   属性可以任意被修改将会导致对象中的数据变得非常不安全
        *   getter方法用来读取属性
        *   setter方法用来设置属性
        *   - 它们被称为属性的存取器
        * */
    get name1(){
        // console.log('get name()执行了!!');
        return this.name1;
    }

    set name1(value){
        this.name1 = value;
    }
}

const person = new Person(); //创建实例对象

//实例属性和方法通过实例对象调用
console.log(person.name)
console.log(person.say())
//静态属性和方法通过类调用
console.log(Person.sex)
console.log(Person.skill())

构造函数

示例:
class Person {
    name: string;
    age: number;

    // constructor 被称为构造函数
    //  构造函数会在对象创建时调用
    constructor(name: string, age: number) {
        // 在实例方法中,this就表示当前当前的实例
        // 在构造函数中当前对象就是当前新建的那个对象
        // 可以通过this向新建的对象中添加属性
        this.name = name;
        this.age = age;
    }
    
}

const person = new Person(name: '李四', age: 20)

继承

class Person {
    name: string;
    age: number;

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

    say() {
        console.log("父类实例方法")
    }
    
}

//继承 extends

示例:
class Person1 extends Person {
    sport() {
        console.log("子类中新增的方法")
    }
    
    say() {
        console.log("子类方法覆盖父类方法")
    }
}

/*
    * Person1 extends Person
    *   - 此时,Person被称为父类,Person1被称为子类
    *   - 使用继承后,子类将会拥有父类所有的方法和属性
    *   - 通过继承可以将多个类中共有的代码写在一个父类中,
    *       这样只需要写一次即可让所有的子类都同时拥有父类中的属性和方法
    *       如果希望在子类中添加一些父类中没有的属性或方法直接加就行
    *   - 如果在子类中添加了和父类相同的方法,则子类方法会覆盖掉父类的方法
    *       这种子类覆盖掉父类方法的形式,我们称为方法重写
    *
 * */

const person1 = new Person1(name: '李四', age: 20)
person1.sport() //此时控制台输出 '子类中新增的方法'
person1.say() //此时控制台输出 '子类方法覆盖父类方法'

super关键字

示例:
class Person {
    name: string;
    age: number;

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

    say() {
        console.log("父类实例方法")
    }
}

class Person1 extends Person {
    constructor(name: string, age: number) {
        // 如果在子类中写了构造函数,在子类构造函数中必须对父类的构造函数进行调用
        super(name, age); // 调用父类的构造函数
    }

    sport() {
        console.log("子类中新增的方法")
    }
    
    say() {
        // 在类的方法中 super就表示当前类的父类
        super.say(); //控制台输出 '父类实例方法'
        console.log("子类方法覆盖父类方法")
    }
}

const person1 = new Person1(name: '李四', age: 20)

抽象类

示例:
/*
*   以abstract开头的类是抽象类,
*       抽象类和其他类区别不大,只是不能用来创建对象(不能通过new创建实例对象)
*       抽象类就是专门用来被继承的类
*       抽象类中可以添加抽象方法
* */
abstract class Person {
    name: string;
    age: number;

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

    // 定义一个抽象方法
    // 抽象方法使用 abstract开头,没有方法体
    // 抽象方法只能定义在抽象类中,子类必须对抽象方法进行重写
    abstract say():void;

}

class Person1 extends Person {
    say() {
        console.log("子类方法覆盖父类方法")
    }
}

const person1 = new Person1(name: '李四', age: 20);
person1.say();

接口

interface关键字开头
接口用来定义一个类结构,用来定义一个类中应该包含哪些属性和方法
同时接口也可以当成类型声明去使用
interface person {
    name: string;

    say():void;
}

/*
*   接口可以在定义类的时候去限制类的结构,
*   接口中的所有的属性都不能有实际的值
*   接口只定义对象的结构,而不考虑实际值
*   在接口中所有的方法都是抽象方法
*
* */

/*
* 定义类时,可以使类去实现一个接口,
*   实现接口就是使类满足接口的要求
* */
class MyClass implements person{
    name: string;

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

    say(){
        console.log('大家好~~');
    }

}

泛型

在定义函数或是类时,类型不明确时就可以使用泛型
function person<A>(name: A): A{
    return name;
}

// 可以直接调用具有泛型的函数
let a = person(10); // 不指定泛型,TS可以自动对类型进行推断
let b = person<string>('张三'); // 指定泛型

// 泛型可以同时指定多个
function person1<A, B>(a: A, b: B):T{
    console.log(b);
    return a;
}
person1<number, string>(111, '张三');