Is it possible to call an overridden method from a native type?
Consider this:
class Foo { def foo = "foo" } trait Bar { self: Foo => override def foo = "bar" } I was pleasantly surprised to learn that this is possible, and it works as expected:
new Foo with Bar foo returns "bar". The question is whether Bar.foo call Foo.foo , as is often the case with "normal" inheritance. override def foo = super.foo + "bar" does not work (says: "foo is not a member of AnyRef), and does not do override def foo = self.foo + "bar" (it ends up just calling itself, and leads to infinite recursion.) I tried several other combinations (like self.Foo.foo , Foo.this.foo , etc.), but no luck.
Is it just not possible?
No. Cannot invoke overridden method from type self.
First, the attribute Bar not a successor of the Foo class, so it is impossible to use super.foo .
And secondly, it is also impossible to use self.foo , since self is of type Bar with Foo . This can be shown by printing the program after typer :
$ scalac -Xprint:typer test.scala [[syntax trees at end of typer]] // test.scala package <empty> { class Foo extends scala.AnyRef { def <init>(): Foo = { Foo.super.<init>(); () }; def foo: String = "foo" }; abstract trait Bar extends scala.AnyRef { self: Bar with Foo => def /*Bar*/$init$(): Unit = { () }; override def foo: String = "bar" }; class FooBar extends Foo with Bar { def <init>(): FooBar = { FooBar.super.<init>(); () } }; object TestApp extends scala.AnyRef { def <init>(): TestApp.type = { TestApp.super.<init>(); () }; def main(args: Array[String]): Unit = { val a: FooBar = new FooBar(); scala.this.Predef.println(a.foo) } } } So, using self.foo you are trying to access the Foo method of the Bar attribute. This behavior complies with the Scala Specification (PDF):
The sequence of template operators may have a prefix with a formal parameter definition and arrow, for example. x =>, or x: T =>. If a formal parameter is specified, it can be used as an alias to refer to this throughout the body of the template. If a formal parameter with type T appears, this definition affects type S of the base class or object as follows: let C be the class type or attribute or object that defines the template. If type T is given for a formal eigenparameter, S is the largest lower boundary of T and C. If no type T is specified, S is only C. Inside the template, this type is assumed to be S.
You can access the method using reflection, but I think this is not what you are looking for.
I do not know any specific syntax to separate the base class and the mixed attribute. However, there is a simple solution to achieve the result manually by extracting the overridden method from the default implementation in the base class:
class Foo { def foo = defaultFoo; def defaultFoo = "foo" } trait Bar { self: Foo => override def foo = self.defaultFoo + "bar" } As expected
new Foo with Bar foo == "foobar" new Foo foo == "foo" You increase your Foo attribute instead of using the self type:
class Foo {def foo = "foo"} trait Bar extends Foo { override def foo = super.foo + "bar" } new Foo with Bar foo // barfoo See also this answer .