Ответ 1
Нет. Невозможно вызвать переопределенный метод из типа self.
Во-первых, признак Bar
не является преемником класса Foo
, поэтому невозможно использовать super.foo
.
А во-вторых, также невозможно использовать self.foo
, поскольку self
имеет тип Bar with Foo
. Это можно показать, распечатав программу после 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)
}
}
}
Итак, с помощью self.foo
вы пытаетесь получить доступ к методу Foo
признака Bar
. Такое поведение соответствует Scala Спецификация (PDF):
Последовательность операторов шаблона может иметь префикс с формальным определение параметра и стрелка, например. x = > , или x: T = > . Если формальный параметр указан, его можно использовать как псевдоним для ссылки на этот по всему телу шаблона. Если появляется формальный параметр с типом T это определение влияет на тип S типа базовый класс или объект следующим образом: пусть C - тип класса или признак или объект, определяющий шаблон. Если тип T задан для формальный собственный параметр, S - наибольшая нижняя граница T и C. Если нет тип T задается, S - всего C. Внутри шаблона тип этого предполагается, что S.
Можно получить доступ к методу с использованием отражения, но я думаю, что это не то, что вы ищете.