Jesus J
Jesus J

Reputation: 95

Using mixin composition with functions in scala

I'm trying to use mixin composition using functions, but I have an error in the apply method of obj object:

Overriding method apply in trait t of type (s: String)String; method apply needs abstract override modifiers.

How to solve this error and which is the correct implementacion?

trait t extends Function1[String,String] {
  abstract override def apply(s: String): String = {
    super.apply(s)
    println("Advice" + s)
    s
  }
}

object MixinComp {
  def main(args: Array[String]) {
    val obj = new Function1[String, String] with t {
      override def apply(s: String) = s
    }
    println(obj.apply("Hi"))
  }
}

Upvotes: 0

Views: 297

Answers (2)

Dima
Dima

Reputation: 40510

Your immediate problem (the reason it complains about the error) is that you can't have an abstract call in your linearization flow (your t.apply calls super.apply, which is abstract).

Also, the apply method you define in the top level anonymous class overrides everything, and does not call super, making the t being mixed in completely irrelevant.

Something like this would solve both problems:

trait t extends Function1[String,String] {
  abstract override def apply(s: String): String = {
    println("Advice" + s)
    super.apply(s) // I rearranged this a little, because it kinda makes more sense this wat
  }
}

 // Note, this extends `Function1`, not `t`, it, just a "vanilla" Function1
class foo extends Function1[String, String] {
   def apply(s: String): String = s
}


// Now I am mixing in the t. Note, that the apply definition 
// from foo is now at the bottom of the hierarchy, so that 
// t.apply overrides it and calls it with super 
val obj = new foo with t
obj("foo")

Upvotes: 1

Samar
Samar

Reputation: 2101

You won't need to use the abstract modifier in your t trait definition, if you don't call the super.apply. And in this particular case I dont see any need for calling super.apply as Function1's apply is abstract. You probably need custom apply implementations. The following code should work.

trait t extends Function1[String, String] {
  override def apply(s: String): String = {
    // super.apply(s)
    println("Advice" + s)
    s
  }
}

Case1: use the overridden apply method in t trait:

val obj = new Function1[String, String] with t {} 
obj.apply("hello") // prints: Advicehello

Case 2: override the apply method in t trait in an anonymous class:

val obj = new Function1[String, String] with t {
  override def apply(s: String): String = s
}

obj.apply("hello") // prints hello

Upvotes: 0

Related Questions