简体   繁体   English

特质抽象方法

[英]Trait abstract method

How to define a trait with an abstract method that need to be present even tho it can have different arguments. 如何使用需要存在的抽象方法定义特征,即使它可以具有不同的参数。 I just want to make sure the class that extends the trait has the method and the same return type. 我只想确保扩展特征的类具有方法和相同的返回类型。 The example bellow (mainly illustrative) overloads the "add" and gives an error that "add" needs to be defined. 下面的示例(主要是说明性的)重载“添加”并给出需要定义“添加”的错误。 How should I change the method declaration in the Trait? 我该如何更改Trait中的方法声明?

Unfortunately all the answers don't work. 不幸的是,所有答案都不起作用。 I am not sure if I was clear, but I don't want to have any defined types in the arguments to be defined/checked (Any, generic, type definition) as the type of it and number of arguments can change, in my case the return could be the same. 我不确定我是否清楚,但我不希望定义/检查的参数中有任何已定义的类型(任何,泛型,类型定义),因为它的类型和参数的数量可以改变,在我的返回的情况可能相同。 I just want it to check if a method with the same name and return is present ignoring the arguments. 我只是想要检查是否存在具有相同名称和返回的方法而忽略参数。 "Any" is not an alternative as it is not typesafe and I want to define clearly what the functions expect as arguments. “任何”不是替代品,因为它不是类型安全的,我想清楚地定义函数期望作为参数。

Example: 例:

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 = {...}
}

An explanation of the problem 对问题的解释

In Scala the methods/functions def method(x: Int) : Boolean def method() : Boolean def method() : String are different. 在Scala中方法/函数def method(x: Int) : Boolean def method() : Boolean def method() : String是不同的。

By chance they have the same name, but for this semantic connection the Scala compiler does not care. 它们具有相同的名称,但是对于这种语义连接,Scala编译器并不关心。 So as you only would describe the return type but not the arguments of the function you would not supply enough information to the compiler for the definition of a trait. 因此,您只能描述return type而不是函数的arguments ,因此您无法为编译器提供足够的信息来定义特征。 An option could be to give the most generic type Any and any number of arguments. 一个选项可以是给出最通用的类​​型Any和任意数量的参数。 An matching just based on the function name would by normal means not be possible. 仅通过基于函数名称的匹配将是不可能的。 One could use reflection for this but this would pretty likely end up in a hack with a lot of expensive overhead. 人们可以使用reflection ,但这很可能会导致很多昂贵的开销。

Here are some possible solutions using standard language features: 以下是一些使用标准语言功能的可能解决方案

Any number of arguments any kind of input 任何数量的参数任何类型的输入

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

Any number of arguments input type given by type parameter 由type参数给出的任意数量的参数输入类型

// 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
}

Alternate solution with method that has no restrictions given 使用没有限制的方法的替代解决方案

// 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
}

How about something like this? 这样的事怎么样?

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

That would work for all of your named cases by using varargs. 通过使用varargs,这适用于所有已命名的案例。 However this won't work if you want to pass parameters of different types, but will work with any number of Int arguments. 但是,如果要传递不同类型的参数,这将无效,但可以使用任意数量的Int参数。

See this question 看到这个问题

If you want to be super dynamic and don't care about typesafety you could also change the parameter type to Any* , but there's probably a better way to do that which doesn't sacrifice typesafety. 如果你想要超级动态并且不关心类型安全,你也可以将参数类型更改为Any* ,但是可能有更好的方法来做到这一点,不会牺牲类型安全性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM