抽象类和接口使用场景

抽象类(Abstract Classes)通常用于以下场景

  1. 定义基类:抽象类可以作为一个类族的基类,提供了一种组织类层次结构的方式。它通常包含一系列子类共享的属性和方法,并且可以包含抽象方法,强迫子类去实现这些方法。

    示例:在动物模拟系统中,可以定义一个抽象的 Animal 类,其中包含所有动物共有的属性(如名字、年龄)和抽象方法(如 eatsleep),然后具体的动物类(如 DogCat)继承并实现抽象方法。

  2. 实现模板方法设计模式:抽象类可以定义一个算法的骨架,允许子类在不改变算法结构的前提下,重写某些步骤的方法。模板方法是一个在抽象类中定义的最终方法(final method),它调用了若干个抽象方法或钩子方法(hook methods),这些方法由子类实现。

    示例:一个抽象的 ReportGenerator 类可以定义一个 generateReport 模板方法,该方法内部调用了几个抽象方法,如 getData, formatData,具体报告生成器(如 DailyReportGeneratorWeeklyReportGenerator)继承并实现这些抽象方法。

接口(Interfaces)通常用于以下场景

  1. 定义规范或契约:接口定义了一组方法签名,表明实现该接口的类必须提供这些方法。它只关注对象的行为,不关心其实现细节,有利于实现松耦合的设计。

    示例:在 GUI 库中,可以定义一个 Button 接口,规定了 renderonClick 等方法,任何想要成为按钮控件的类都必须实现这个接口。

  2. 实现多态和依赖倒置原则:接口可以让类之间的耦合度降低,使得高层模块不受底层模块变动的影响。在设计中,模块间的依赖应该是基于接口而不是具体实现。

    示例:服务提供者注册到服务消费者时,消费者依赖于服务接口而不是具体的实现类,这样当服务提供者发生变化时,只要保持接口不变,消费者就不需要更改。

  3. 实现多重继承效果:TypeScript 类只能单继承,但一个类可以实现多个接口,从而实现类似多重继承的效果,能够聚合多个独立的行为特征。

    示例:一个类可以同时实现 ReadableWritableSeekable 接口,表明它可以像读取流、写入流一样工作,并且支持定位操作。