scala 使用重载方法扩展 class

scala extend class with overloaded method

我正在尝试使用重载方法扩展 class,这样我就可以实例化它并传递不同数量的参数,但保留 Foo 和 Bar 的通用类型。如何让我的代码可运行?

class GenericClass {
  def run(x: Int): Unit
  def run(x: Int, y: Int): Unit
}

class Foo extends GenericClass {
  def run(x: Int): Unit
}

class Bar extends GenericClass {
  def run(x: Int, y: Int)
}

def getRun(hello: String) = {
  hello match {
        case "foo" => new Foo
        case "bar" => new Bar
        }
}

def execIt(runType: String) = {
    case "foo" => getRun(runType).run(2)
    case "bar" => getRun(runType).run(2, 3)
}

execIt("foo")

你可以尝试引入类型成员

trait GenericClass {
  type In
  def run(x: In): Unit
}

class Foo extends GenericClass {
  override type In = Int
  override def run(x: Int): Unit = println("Foo#run")
}

class Bar extends GenericClass {
  override type In = (Int, Int)
  override def run(x: (Int, Int)): Unit = println("Bar#run")
}

def getRun(hello: String) = {
  hello match {
    case "foo" => new Foo
    case "bar" => new Bar
  }
}

def execIt(runType: String) = getRun(runType) match {
  case foo: Foo => foo.run(2)
  case bar: Bar => bar.run(2, 3)
}

execIt("foo") // Foo#run

或类型class

trait GenericClass
class Foo extends GenericClass
class Bar extends GenericClass

trait Run[A <: GenericClass, T] {
  def run(a: A, t: T): Unit
}
object Run {
  implicit val foo: Run[Foo, Int] = (a, t) => println("Run.foo")
  implicit val bar: Run[Bar, (Int, Int)] = (a, t) => println("Run.bar")
}

implicit class RunOps[A <: GenericClass](val a: A) extends AnyVal {
  def run[T](t: T)(implicit r: Run[A, T]): Unit = r.run(a, t)
}

def getRun(hello: String) = {
  hello match {
    case "foo" => new Foo
    case "bar" => new Bar
  }
}

def execIt(runType: String) = getRun(runType) match {
  case foo: Foo => foo.run(2)
  case bar: Bar => bar.run(2, 3)
}

execIt("foo") // Run.foo

请注意我也修改了execIt

您也可以保持一切不变,只为不需要的方法抛出 NotImplementedError

trait GenericClass {
  def run(x: Int): Unit
  def run(x: Int, y: Int): Unit
}

class Foo extends GenericClass {
  def run(x: Int): Unit = println("Foo#run")
  def run(x: Int, y: Int): Unit = ???
}

class Bar extends GenericClass {
  def run(x: Int): Unit = ???
  def run(x: Int, y: Int) = println("Bar#run")
}

def getRun(hello: String) = {
  hello match {
    case "foo" => new Foo
    case "bar" => new Bar
  }
}

def execIt(runType: String) = runType match {
  case "foo" => getRun(runType).run(2)
  case "bar" => getRun(runType).run(2, 3)
}

execIt("foo") // Foo#run

尽管最后一个选项似乎滥用了 OOP。