This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Abstract overrides?

2 replies
Kris Nuttycombe
Joined: 2009-01-16,
User offline. Last seen 42 years 45 weeks ago.

I'm confused as to the semantics of abstract overrides. From
Programming in Scala, my interpretation was that a trait with a method
defined with the "abstract override" modifier could only be mixed into
a class that provides a concrete implementation of the method.
However, this doesn't appear to quite be the case, at least in 2.7.5:

object Test3 {
type Binding = String => String

trait ABinding extends Binding {
abstract override def apply(s: String): String = super.apply(s) + "a"
}

object BBinding extends Binding with ABinding {
override def apply(s: String) = s + "b"
}

def main(args: Array[String]) {
println(BBinding("main"))
}
}

knuttycombe@knuttycombe-ubuntu:~/tmp/scala$ scalac Test3.scala
Test3.scala:9: error: error overriding method apply in trait ABinding
of type (String)String;
method apply needs `abstract override' modifiers
override def apply(s: String) = s + "b"
^
one error found

Here, I expected that BBinding would provide the concrete
implementation of apply() needed to allow ABinding to be mixed in. Why
is this not the case?

The following works:

object Test3 {
type Binding = String => String

trait ABinding extends Binding {
abstract override def apply(s: String): String = super.apply(s) + "a"
}

private class BBinding extends Binding {
override def apply(s: String) = s + "b"
}

object CBinding extends BBinding with ABinding

def main(args: Array[String]) {
println(CBinding("main"))
}
}

So once there's a concrete class that defines the base case, things
work fine. Is it universally the case that a class cannot directly
extend a trait which defines a method as "abstract override def" by
providing a concrete implementation, and that an intermediary class
must be defined?

Thanks,

Kris

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Abstract overrides?


On Fri, Jun 26, 2009 at 2:46 PM, Kris Nuttycombe <kris [dot] nuttycombe [at] gmail [dot] com> wrote:
I'm confused as to the semantics of abstract overrides. From
Programming in Scala, my interpretation was that a trait with a method
defined with the "abstract override" modifier could only be mixed into
a class that provides a concrete implementation of the method.
However, this doesn't appear to quite be the case, at least in 2.7.5:

object Test3 {
 type Binding = String => String
  Binding = Function1[String,String], so it defines apply(String): String.  


 trait ABinding extends Binding {
   abstract override def apply(s: String): String = super.apply(s) + "a"
 }

 object BBinding extends Binding with ABinding {
   override def apply(s: String) = s + "b"
 }
  Here is the order of inheritance: [Function1's supers] Function1 ABinding { override def apply(s : String) = s + "b" } -- a structural type, iirc.   I changed the abstract override defintion just to get this compiled. Here is the compiled tree of it:   scala> :tree Test3
object Test3 extends scala.ScalaObject {
  def <init>() = {
    super.<init>();
    ()
  };
  type Binding = _root_.scala.Function1[String, String];
  abstract trait ABinding extends Binding with scala.ScalaObject {
    def $init$() = {
      ()
    };
    def x(s: String): String = "a"
  };
  object BBinding extends Binding with ABinding with scala.ScalaObject {
    def <init>() = {
      super.<init>();
      ()
    };
    override def apply(s: String) = s.$plus("b")
  }
} (ModuleDef)   See?  

--
Daniel C. Sobral

Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
Frank Teubler
Joined: 2009-01-22,
User offline. Last seen 3 years 37 weeks ago.
Re: Abstract overrides?

trait ABinding should be mixed in, so it really overrides the apply method

object Test3 {
type Binding = String => String

trait ABinding extends Binding {
abstract override def apply(s: String): String = super.apply(s) + "a"
}

class BBinding extends Binding {
def apply(s: String) = s + "b"
}

def main(args: Array[String]) {
val bind = new BBinding with ABinding // <------- here it happens
println(bind("main"))
}
}

Frank

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland