4. TS 中的类 及其属性、方法、继承

1,827 阅读5分钟

一、ts 类

1. 定义一个简单的 类

constructor() {} 实例化的时候触发构造函数

class Person{
    // 定义一个类的属性变量名
    name:string;

    //  实例化的时候触发构造函数
    constructor(n:string) {
        // 把 n 值赋值给 类中的属性
        this.name = n;
    }
    
    // 定义一个类的方法
    run() {
        console.log(this.name)
    }
}

var p = new Person('xl');
alert(p.run())

2. ts 类中获取调用方法和设置属性值

class Person {
    name:string;
    constructor(name:string) {
        this.name = name;
    }
    getName() {
        return this.name
    }
    setName(name:string) {
        this.name = name;
    }
}

let p  = new Person('xl')

alert(p.getName())

p.setName('gg')
alert(p.getName())

3. ts 中 static 静态方法和静态属性

ts 中的 静态属性和方法 需要通过 static 这个关键字来进行加持
静态方法里不能直接调用类里面的属性, 调用类里面的属性这里会返回【undefined】
静态方法里调用静态属性直接通过类名.静态属性名

class Person{

    name:string;
    
    age = 6;
    
    // 添加静态属性
    static sex = '男'

    constructor(name:string) {
        this.name = name;
    }
    run() {
        return `${this.name}跑步`
    }
    
    // 添加静态方法
    static work() {
    // 静态方法里不能直接 this.age 这样调用类里面的属性, 类里面的属性这里会返回【undefined】
        // return this.age   // undefined
        
        // 静态方法里调用静态属性直接通过类名.静态属性名
        // return `gg工作${Person.sex}`   // gg工作男
    }
}
// 调用静态方法
alert(Person.work())

// 调用静态属性
alert(Person.sex)   // 男

二、ts 类中的继承 extends

1. 子类继承父类的属性和方法

super(参数名...) 这里的作用是初始化父类的构造函数

class Person{
    name:string;

    constructor(name:string) {
        this.name = name;
    }
    run() {
        return this.name + '在运动'
    }
}

class Web extends Person {
    constructor(name:string) {
        // super 这里的作用是初始化父类的构造函数
        super(name)
    }
}

let w = new Web('gg')
console.log(w.run())

2. 当父子类的方法名一致时

ts 中继承:子类的方法和父类的方法一致,调用子类的方法
当子类中的方法和父类中的方法相同的时候,优先调用子类自己定义的方法

class Person{

    name:string;
    
    constructor(name:string) {
        this.name = name ;
    }
    
    run() {
        return this.name + '在运动'
    }
}

class Web extends Person{

    constructor(name:string) {
        super(name)
    }
    
    work() {
        return this.name +'在工作'
    }
    
    run() {
        return this.name + '在跑步'
    }
}

let w = new Web('gg')
alert(w.run())   // 在跑步

3. 类的继承多态

ts 继承:多态:父类定义一个方法不去实现,让继承它的子类去实现,每一个子类有不同的表现,多态属于继承

class Animal{
    name:string;

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

    eat() {
        // 父类定义一个方法不实现,让继承它的子类去实现,每一个子类有不同的表
    }
}

class Dog extends Animal{
    constructor(name:string) {
        super(name)
    }

    eat() {
        return `${this.name} 吃骨头`
    }
}

class Cat extends Animal{
    constructor(name:string) {
        super(name)
    }

    eat() {
        return `${this.name} 吃老鼠`
    }
}
let dog = new Dog('小狗')
let cat = new Cat('小猫')

alert(dog.eat())  // 小狗 吃骨头
alert(cat.eat())  // 小猫 吃老鼠

4. ts 类继承抽象类

abstract 关键字定义抽象类和抽象方法,抽象类中的抽象方法不包含具体实现并且必须在派生类中实现

抽象类是无法创建抽象类的实例的

abstract 抽象方法只能出现在抽象类中

抽象类和抽象方法是用来定义一个标准比如标准: Animal 这个类要求它的子类必须包含 eat 方法。

a. 抽象方法只能出现在抽象类中

错误写法

class Animal{

    name:string;

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

    // 抽象方法只能出现在抽象类中
    abstract eat():any
}

正解

image.png

b. 抽象类是无法创建抽象类的实例的

错误写法

abstract class Animal{

    name:string;

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

// 【语法报错】 抽象类是无法创建抽象类的实例的
var dog = new Animal('小狗')

正解不能 new Animal

image.png

c. 抽象类中的抽象方法不包含具体实现并且必须在派生类中实现

错误写法

abstract class Animal{
    name:string;

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

    // 方法“eat”不能有实现,因为它被标记为抽象。
    abstract eat() {
    
   }
}

class Dog extends Animal{
    constructor(name:string) {
        super(name)
    }
    eat() {
        return `${this.name}吃 骨头`
    }
}

let dog = new Dog('小狗')
alert(dog.eat())  // undefined   上面的抽象类的方法“eat”不能有实现,因为它被标记为抽象。

错误写法示图

image.png

正解abstract eat():any

image.png

d. 抽象类也可以实现继承多态化

抽象类也可以实现继承多态化

abstract class Animal{
    name:string;

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

    abstract eat():any
}

class Dog extends Animal{
    constructor(name:string) {
        super(name)
    }

    eat() {
        return `${this.name}吃 骨头`
    }
}


class Cat extends Animal{
    constructor(name:string) {
        super(name)
    }

    eat() {
        return `${this.name}吃 鱼`
    }
}
// 抽象类也可以实现继承多态化
let dog = new Dog('小狗')
alert(dog.eat())  // 小狗吃 骨头

let cat = new Cat('小猫')
alert(cat.eat())  // 小猫吃 鱼

三、类的修饰符

ts 类里面的修饰符 typescript 里面定义属性的时候给我们提供了三种修饰符:

public: 公有 在当前类里面、子类、类外面都可以访问
protected: 保护类型 在当前类里面、子类里面都可以访问,在类外部都无法访问
private: 私有 在当前类里面可以访问,子类、类外部都无法访问\

属性如果不加修饰符 默认就是公有(public

1. public: 公有修饰符

ts 中用 public 修饰符 来定义公有属性 , 在当前类里面、子类、类外面都可以访问

class Person{
    public name:string;

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

    run() {
        return this.name + '在跑步'
    }
}

class Web extends Person{

    constructor(name:string) {
        super(name)
    }
}

// 在子类可以访问 public 修饰符定义出来的属性
let w = new Web('哈哈')
alert(w.run())

// 在类外部可以访问 public 修饰符定义出来的属性
let p = new Person('开心')
alert(p.name)

2. protected 保护修饰符

ts 中用 protected 保护修饰符 来定义属性 , 在当前类里面、子类里面都可以访问,在类外部都无法访问

class Person{
    protected name:string;

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

    run() {
        return this.name + '在跑步'
    }
}

class Web extends Person{

    constructor(name:string) {
        super(name)
    }
}
// 在子类可以访问 protected 修饰符定义出来的属性
let w = new Web('哈哈')
alert(w.run())


// 在【类外部无法】可以访问 protected 修饰符定义出来的属性
let p = new Person('开心')
// 【语法报错】:属性“name”受保护,只能在类“Person”及其子类中访问。
alert(p.name)

3. private 私有修饰符

ts 中用 private 私有修饰符 来定义属性 , 在当前类里面可以访问子类、类外部都无法访问

class Person{
    private name:string;

    private age = 9;
    
    constructor(name:string) {
        this.name = name;
    }
    private run() {
        return this.name + '在跑步'
    }
}

class Web extends Person{
    constructor(name:string) {
        super(name)
    }
}
let w = new Web('哈哈')
// // 这里是语法错误,虽然能够执行,是因为 把 ts 转换成 了 es5
alert(w.run())


// 在【类外部无法】可以访问 private 修饰符定义出来的属性
let p = new Person('开心')
// 【语法报错】:属性“name”是私有的,只能在类“Person”中访问
// 这里能执行的原因是因为转化成了 es5,语法上这样是错误的。
alert(p.name)

image.png