typescript 类的继承,成员修饰符,抽象类,多态,链式调用

类的继承和成员修饰符

private:为私有属性,只能在当前类中访问,如果 private constructor则该类不能被实例化,不能被继承.
protected:受保护的属性,只能在当前类及其子类中访问,如果protected constructor则该类不能被实例化,但是可以被继承
public:默认为public,公用属性,任何地方都可以访问,在构造函数的参数中使用public arg,则可以不用重新定义arg
static:静态属性,
存在于类本身上面而不是类的实例上,所以只能通过类名来调用,可以继承,通过子类的命名来调用,不可以使用this.来调用
举个栗子:

class Animal {
    constructor(name:string){
        this.name=name;
    }
    public skip(){}
    private name:string; // 私有变量,不能被继承,也不能在外部被访问,只能在类“Animal”中访问
    protected move() { 
        console.log(Animal.food); // 静态属性,只能这么调用
    }
    readonly amount:number = 4;
    static food:string = 'rou';
}

// Cat继承Animal,并将构造函数设为私有
class Cat extends Animal{
    private constructor(name:string){
        super(name)
    }
}
const cat = new Cat(); // 报错  类“Cat”的构造函数是私有的,仅可在类声明中访问
class Jiafei extends Cat{...} // 报错   无法扩展类“Cat”。类构造函数标记为私有

// Dog继承Animal 
class Dog extends Animal {
    constructor(name:string,public color:string){ // color变成实例属性,不需要再定义
        super(name)
        this.color = color;
    }
    private eat:string = '粑粑';
    brek(){ 
        this.amount = 2; //  报错  amount为只读,只能读取不可更改
        this.name(); // 报错   属性“name”为私有属性,只能在类“Animal”中访问
        this.skip(); // 正确 Animal中的public,可以访问
        this.move(); // 正确 Animal中的protected,子类可以访问
        this.eat = Animal.food; // 静态属性,只能这么调用
    } 
}

const dog = new Dog('狗狗','白色');
dog.move(); // 报错  属性“move”受保护,只能在类“Animal”及其子类中访问
dog.name; // 报错   属性“name”为私有属性,只能在类“Animal”中访问
dog.eat; // 报错  属性“color”为私有属性,只能在类“Dog”中访问
dog.skip(); // 正确  公用属性
dog.color; // 正确   公用属性
dog.brek();// 正确   公用属性
Dog.food; //  正确   可以通过子类的命名来调用

抽象类和多态

 抽象类:只能被继承不能被实例化的类,abstract关键字是用于定义抽象类和在抽象类内部定义抽象方法
好处:抽离出代码的公用性,有利于代码的复用性

// 创建一个抽象类Person;
abstract class Person {
    eat(): void {
        console.log('米饭');
    }
    abstract skin(): void; // skin为Person的抽象成员,必须在派生类中实现
}

// 派生类Person
class Chinese extends Person {
    constructor(public name:string) {
        super(); // 在派生类的构造函数中必须调用 super()
    }
    // Chinese不会自动继承Person的skin,所以要手动实现,否则报错
    skin(): void{
        console.log('黄皮肤')
    }   
}

const c = new Person(); // 报错  无法创建抽象类的实例
const chnese = new Chinese('中国人'); // 正确

多态:父类中定义一个方法不去实现,让继承它的子类去实现,每一个子类有不同的表现,也是继承的一种
上面的例子稍微变一变

// eat和skin方法在子类上有各自的实现逻辑,这就是多态
abstract class Person {
    eat(): void{}
    abstract skin(): void
}
class Chinese extends Person {
    eat(): void{console.log('吃米饭')}
    skin(): void{console.log('黄皮肤')}
}
class American extends Person {
    eat(): void{console.log('吃面包')} 
    skin(): void{console.log('白皮肤')} 
}

const chnese = new Chinese(); // 正确
const american = new American(); // 正确

const personArr:Person[] = [chnese, american];
personArr.forEach(item=>{
    item.eat(); 
    item.skin();
})

拓展

链式调用:类里面的方法返回this,子类可以继承,可以保持父类子类调用的连贯性

// 这就实现了一个简单的链式调用
class ParentChain{
    ch1(){return this};
    ch2(){return this};
}
const parentChain = new ParentChain();
parentChain.ch1().ch2()

// 子类可以继承。
class MyChain extends ParentChain{
    next(){return this;}
}
const myChain = new MyChain();
myChain.next().ch2().next().ch1(); // 子类父类相互调用

猜你喜欢

转载自blog.csdn.net/l284969634/article/details/105134071
今日推荐