Scala将方法传递给超级构造函数

Scala将方法传递给超级构造函数,scala,constructor,functional-programming,Scala,Constructor,Functional Programming,我希望有一个层次结构,其中基类可以在其构造函数中使用函数,派生类可以提供一个方法作为该函数。下面有一种方法,但很难看。我必须在超级构造函数的构造函数arg列表中声明子函数。这意味着函数是匿名的,因此不是子类的方法(尽管我并不关心这个问题)。真正的代码将很长,并且最终很难阅读,特别是如果我有多个函数的话 因此: w1.go打印“你好,世界”,w2.B类打印“嘿,伙计们”。这就是我想要的,但是有没有办法让w成为类B的方法或val,并且仍然将其传递给super的构造函数 您可以这样做,让您作为抽象成员

我希望有一个层次结构,其中基类可以在其构造函数中使用函数,派生类可以提供一个方法作为该函数。下面有一种方法,但很难看。我必须在超级构造函数的构造函数arg列表中声明子函数。这意味着函数是匿名的,因此不是子类的方法(尽管我并不关心这个问题)。真正的代码将很长,并且最终很难阅读,特别是如果我有多个函数的话

因此:


w1.go打印“你好,世界”,w2.B类打印“嘿,伙计们”。这就是我想要的,但是有没有办法让
w
成为类B的方法或val,并且仍然将其传递给super的构造函数

您可以这样做,让您作为抽象成员传入的函数,然后在您的案例类中实现它,并提供通过构造函数接受它的预封装实现:

  abstract class A(s1: String, s2: String) {
    def w: (String, String) => Unit
    def go(): Unit = {
      w(s1, s2)
    }
  }

  class InlineA(s1: String, s2: String, w1: (String, String) => Unit) extends A(s1, s2) {
    def w = w1
  }

  val externalWriter = { (s1: String, s2: String) =>
    println(s1 + s2)
  }

  val w1 = new InlineA("Hello ", "world", externalWriter)
  w1.go()

  case class B(s1: String, s2: String) extends A(s1, s2) {
    def w = { (a: String, b: String) =>
      println("Class B:" + a + b)
    }
    def write(): Unit = go()
  }

  val w2 = B("Hey  ", "guys")
  w2.go()

您可以这样做,让您作为抽象成员传递的函数,然后在您的案例类中实现它,并提供通过构造函数接受它的预封装实现:

  abstract class A(s1: String, s2: String) {
    def w: (String, String) => Unit
    def go(): Unit = {
      w(s1, s2)
    }
  }

  class InlineA(s1: String, s2: String, w1: (String, String) => Unit) extends A(s1, s2) {
    def w = w1
  }

  val externalWriter = { (s1: String, s2: String) =>
    println(s1 + s2)
  }

  val w1 = new InlineA("Hello ", "world", externalWriter)
  w1.go()

  case class B(s1: String, s2: String) extends A(s1, s2) {
    def w = { (a: String, b: String) =>
      println("Class B:" + a + b)
    }
    def write(): Unit = go()
  }

  val w2 = B("Hey  ", "guys")
  w2.go()

我会做一些类似于monkjack的解决方案的事情,但更多地使用混合模式。这里的关键区别在于,我使用了
A
的匿名细化来创建
w1
,允许我保留
w
作为一种方法

abstract class A(s1: String, s2: String) {
  def w(arg1: String, arg2: String): Unit
  def go(): Unit = {
    w(s1, s2)
  }
}

val w1 = new A("Hello", "World") {
  def w(a: String, b: String): Unit = println(a + b)
}
w1.go()

case class B(s1: String, s2: String) extends A(s1, s2) {
  def w(a: String, b: String): Unit = println("Class B:" + a + b)
  def write: Unit = go
}

val w2 = B("Hey  ", "guys")
w2.write

trait C {
  def w(a: String, b: String): Unit = println("Trait C:" + a + b)
}

val w3 = new A("Bye ", "everyone") with C
w3.go()

我会做一些类似于monkjack的解决方案的事情,但更多地使用混合模式。这里的关键区别在于,我使用了
A
的匿名细化来创建
w1
,允许我保留
w
作为一种方法

abstract class A(s1: String, s2: String) {
  def w(arg1: String, arg2: String): Unit
  def go(): Unit = {
    w(s1, s2)
  }
}

val w1 = new A("Hello", "World") {
  def w(a: String, b: String): Unit = println(a + b)
}
w1.go()

case class B(s1: String, s2: String) extends A(s1, s2) {
  def w(a: String, b: String): Unit = println("Class B:" + a + b)
  def write: Unit = go
}

val w2 = B("Hey  ", "guys")
w2.write

trait C {
  def w(a: String, b: String): Unit = println("Trait C:" + a + b)
}

val w3 = new A("Bye ", "everyone") with C
w3.go()

我不知道你能在一个新的,非常有趣的物体中定义w。缺点是你必须知道使用它@monkjack会明确这个选项。此外,如果它有一个长的
w
定义,那么这将是相当冗长的,因为它将在使用它的范围内内联。嗯……虽然很聪明,但在很多情况下都很有用。如果你不想内联执行,你也可以在另一个特性中定义
w
,并在实例化时混合该特性。我再加一个例子好的,现在你有了。我一直在为如何利用这些特质而挣扎。现在,您只需为任意编写器定义一个新特性,并在实例化时使用简单的
和N
混合。你教了我一些非常有用的东西,我希望其他人会觉得这很有用。我不知道你能在一个新的、非常有趣的文本中定义w。缺点是你必须知道使用它@monkjack会明确这个选项。此外,如果它有一个长的
w
定义,那么这将是相当冗长的,因为它将在使用它的范围内内联。嗯……虽然很聪明,但在很多情况下都很有用。如果你不想内联执行,你也可以在另一个特性中定义
w
,并在实例化时混合该特性。我再加一个例子好的,现在你有了。我一直在为如何利用这些特质而挣扎。现在,您只需为任意编写器定义一个新特性,并在实例化时使用简单的
和N
混合。你教了我一些非常有用的东西,我希望其他人会觉得这很有用。