Typescript中抽象类与接口详细对比与应用场景介绍

Typescript中抽象类与接口详细对比与应用场景介绍

  1. 抽象类当做父类,被继承。且抽象类的派生类的构造函数中必须调用super();接口可以当做“子类”继承其他类
    抽象类派生:
abstract class Human {
    constructor (readonly name:string) {}
     
}
 
class Student extends Human {
    constructor (name:string) {
        super(name)
    }
}

接口继承类:

class Man {
    job: string;
    constructor (readonly name: string) {}
    earnMoney () {
        console.log(`earning money`)
    }
}
 
interface HumanRule extends Man{
    nose: string;
    mouth: string;
    ear: string;
    eye: string;
    eyebrow: string
}

当类被接口继承时,通常是需要为这个类的子类添加约束。例如下面的例子中,Man类的子类就需要去实现特定的五官属性,否则将会报错。

class Player extends Man implements HumanRule{
    nose: string;
    mouth: string;
    ear: string;
    eye: string;
    eyebrow: string
    constructor (name) {
        super(name);
    }
}

2. 抽象类与接口都无法实例化, 类类型接口实际上是一种 抽象类型

按个人理解,在使用类类型的接口时,类类型的接口其实就相当于抽象类的子集。抽象类中除了可以像接口那样只定义不实现外,还可以部分实现,而且也可以使用类型修饰符。

类类型的接口更多的是当做一种抽象的数据类型使用,此处所说的类型通常是某个类的实例类型。

let James: Player = new Player('james');  // 类类型使用
 
class SoccerPlayer extends Player {
    constructor (name) {
        super(name)
    }
 
    playSoccer () {
        console.log(`${this.name} is playing soccer.`)
    }
}
 
function createPlayer (pl: SoccerPlayer, name: string) {  // 类类型调用
    return new SoccerPlayer(name);
}

3. 接口中不能包含具体实现,抽象类中除抽象函数之外,其他函数可以包含具体实现

abstract class Human {
    constructor (readonly name:string) {}
    protected thinking () {
        console.log(`I am a human, so i can think, ${this.name} is thinking.`)
    }
}

4. 抽象类中的抽象方法在子类中必须实现, 接口中的非可选项在接口被调用时必须实现。

abstract class Human {
    constructor (readonly name:string) {}
    protected thinking () {
        console.log(`I am a human, so i can think, ${this.name} is thinking.`)
    }
    abstract move (): void
}
 
class Student extends Human {
    constructor (name:string) {
        super(name)
    }
 
    move () {
        console.log(`I am a student, so i move by bus`)
    }
}

而接口一旦调用,就必须要严格实现。此处以函数类型的接口为例:

interface createPlayer {
    (pl: SoccerPlayer, name:string): SoccerPlayer
}
 
let createPlayer:createPlayer = function  (pl: SoccerPlayer, name: string) {  
// 修改createPlayer 使用匿名函数方法创建
    return new SoccerPlayer(name);
}

5. 抽象方法可当做类的实例方法,添加访问修饰符;但是接口不可以

abstract class Human {
    constructor (readonly name:string) {}
    protected thinking () {
        console.log(`I am a human, so i can think, ${this.name} is thinking.`)
    }
    protected abstract move (): void
}

我们为move方法添加abstract标识符,是想让开发者非常明白,Human的派生类中必须要实现此方法;而使用protected标识符,是想限制move方法调用或重载的权限。

综合来说抽象类更多的是实现业务上的严谨性;接口更多的是制定各种规范,而此规范又分为很多类规范,就像官方文档在介绍接口这一节的时候所说的,例如函数型规范、类类型规范、混合规范、索引规范等。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值