首页 > 解决方案 > 构造函数参数与抽​​象成员(类与抽象类)

问题描述

什么时候应该使用抽象类而不是常规类?更具体地说,我试图了解何时应该优先使用构造函数参数而不是抽象成员。

例如:

sealed trait Client

abstract class BaseService {
  def client: Client
}

class Service extends BaseService {
  val client = ???
}

对比

sealed trait Client

class BaseService(client: Client) {}

class Service extends BaseService(client = ???)

据我所知,两者都是有效的。

标签: scalaclassabstract-class

解决方案


正如@Luis Miguel 所说,当您想要声明一组需要由子类实现的通用方法和/或共享将由所有子类使用的一些有限功能时,请使用抽象类。

下面,我列出了一些我认为应该将依赖项传递给构造函数而不是在类/基类中定义它们的原因。

使用依赖注入

(恕我直言)最好为构造函数提供正常运行所需的依赖项 AKA依赖注入

避免紧耦合

当您在类或构造函数中声明依赖项时,您将与依赖项的特定实现紧密耦合Service,这并不理想,被认为是反模式

编程接口,而不是实现

注入依赖项为您提供了更大的灵活性,因为您不耦合到特定的实现。只要您的代码依赖于接口/特征/抽象类(因此避免紧密耦合),这是正确的。

当您的类依赖于接口/特征/抽象类时可能非常强大,因为您可以传递模拟、无操作或客户端的不同策略。因此,请确保您“编程到接口,而不是实现”


推荐阅读