特质抽象方法

时间:2016-03-04 16:48:41

标签: scala

如何使用抽象方法定义特征,即使它可以有不同的参数,也需要存在。我只想确保扩展特征的类具有方法和相同的返回类型。下面的示例(主要是说明性的)重载"添加"并给出错误"添加"需要定义。我应该如何更改Trait中的方法声明?

不幸的是,所有的答案都不起作用。我不确定我是否清楚,但我不想在要定义/检查的参数(任何,泛型,类型定义)中有任何已定义的类型,因为它的类型和参数的数量可以改变,在我的情况下,回报可能是相同的。我只是想要检查是否存在具有相同名称和返回的方法而忽略参数。 "任何"不是替代品,因为它不是类型安全的,我想清楚地定义函数期望作为参数。

示例:

trait X{
  def add: Boolean
}

class Y extends X {
  def add(i: Int, s: String) : Boolean = {...}
}

class W extends X {
  def add(i: Int, y: Int, w: Set[String]) : Boolean = {...}
}

2 个答案:

答案 0 :(得分:5)

问题的解释

在Scala中的方法/功能    def method(x: Int) : Boolean   def method() : Boolean    def method() : String 是不同的。

它们具有相同的名称,但是对于这种语义连接,Scala编译器并不关心。 因此,您只能描述函数的return type而不是arguments,因此您无法为编译器提供足够的信息来定义特征。一个选项可以是提供最通用的类​​型Any和任意数量的参数。 仅通过基于函数名称的匹配将是不可能的。一个可以使用reflection,但这很可能会导致很多昂贵的开销。

以下是使用标准语言功能的一些可能的解决方案:

任意数量的参数任何类型的输入

// any count and any type of input allowed, not much type safety
trait XAny{
  def add(args : Any*): Boolean
}

由类型参数

给出的任意数量的参数输入类型
// any count and any type of input allowed, all input has to be a kind of A
trait XWithType[A]{
  def add(args : A*): Boolean
}

使用没有限制的方法的替代解决方案

// any count and any type of input allowed, all input has to be a kind of A
trait XWithArbitraryMethod{
  def add(): Boolean // here add now would call the real implementation
}

答案 1 :(得分:1)

这样的事情怎么样?

trait X{
   def add(as: Int*): Boolean
} 

通过使用varargs,这适用于所有已命名的案例。但是,如果要传递不同类型的参数,这将无效,但可以使用任意数量的Int个参数。

请参阅this question

如果你想要超级动态并且不关心类型安全,你也可以将参数类型更改为Any*,但是可能有更好的方法来做到这一点。牺牲类型安全。