Is it possible to call an overridden method from self type?

后端 未结 3 637
独厮守ぢ
独厮守ぢ 2021-01-07 23:32

Consider this:

 class Foo { def foo = \"foo\" }
 trait Bar { self: Foo =>
    override def foo = \"bar\"
 }

I was pleasantly surprised

3条回答
  •  滥情空心
    2021-01-08 00:23

    No. It is impossible to call overridden method from a self type.

    Firstly the trait Bar is not a successor of class Foo so it is not possible using super.foo.

    And secondly it is also not possible using self.foo since self is actually of type Bar with Foo. It can be shown by printing the program after typer:

    $ scalac -Xprint:typer test.scala
    [[syntax trees at end of                     typer]] // test.scala
    package  {
      class Foo extends scala.AnyRef {
        def (): Foo = {
          Foo.super.();
          ()
        };
        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 (): FooBar = {
          FooBar.super.();
          ()
        }
      };
      object TestApp extends scala.AnyRef {
        def (): TestApp.type = {
          TestApp.super.();
          ()
        };
        def main(args: Array[String]): Unit = {
          val a: FooBar = new FooBar();
          scala.this.Predef.println(a.foo)
        }
      }
    }
    

    So with self.foo you are trying to access the method foo of the trait Bar. Such behavior matches the Scala Specification (PDF):

    The sequence of template statements may be prefixed with a formal parameter definition and an arrow, e.g. x =>, or x: T =>. If a formal parameter is given, it can be used as an alias for the reference this throughout the body of the template. If the formal parameter comes with a type T, this definition affects the self type S of the underlying class or object as follows: Let C be the type of the class or trait or object defining the template. If a type T is given for the formal self parameter, S is the greatest lower bound of T and C. If no type T is given, S is just C. Inside the template, the type of this is assumed to be S.

    It is possible to access the method using reflection but I think that it is not what you are looking for.

提交回复
热议问题