加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 是否可以从self type调用重写方法?

发布时间:2020-12-16 09:03:00 所属栏目:安全 来源:网络整理
导读:考虑这个: class Foo { def foo = "foo" } trait Bar { self: Foo = override def foo = "bar" } 我惊喜地发现这是可能的,并按预期工作: new Foo with Bar foo 返回“bar”.问题是Bar.foo是否可以调用Foo.foo,就像在“普通”继承情况下经常会做的一样.覆盖
考虑这个:

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

我惊喜地发现这是可能的,并按预期工作:

new Foo with Bar foo

返回“bar”.问题是Bar.foo是否可以调用Foo.foo,就像在“普通”继承情况下经常会做的一样.覆盖def foo = super.foo“bar”不起作用(说“foo不是AnyRef的成员”),也不会覆盖def foo = self.foo“bar”(它最终只是调用自身,并导致无限大递归).
我尝试了一些其他组合(如self.Foo.foo,Foo.this.foo等),但没有任何运气.

这是不可能的吗?

解决方法

不可以从自己的类型调用重写方法.

首先,特征栏不是Foo类的继承者,所以不可能使用super.foo.

其次,也不可能使用self.foo,因为自己实际上是与Foo类型的Bar.可以通过在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,你试图访问trait Bar的方法foo.这种行为符合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.

可以使用反射来访问该方法,但我认为这不是您要查找的.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读