可以覆盖内在特质的成员吗?

时间:2013-12-03 14:33:47

标签: scala inheritance inner-classes method-overriding

扩展外部类时是否可以覆盖内部特征的成员?像

class Foo {
  trait Bar {
    def bar = Set("a", "b")
  }

  class Baz extends Bar
  object Baz {
    def apply() = new Baz
  }
}

我是否可以以任何形式创建f的{​​{1}}个实例,例如Foo

澄清:类f.Baz().bar == Set("c", "d")是给定的,我无法更改它。它调用Foo,所以我也无法改变它。因此,可能无法在Baz()Bar

中优化覆盖内容

2 个答案:

答案 0 :(得分:0)

修改

根据您的澄清,您似乎想要做的是覆盖对象Baz。这通常是不可能的,但如果您使用实验编译器标志-Yoverride-objects,则可以执行以下操作:

class SubFoo extends Foo {
  class Baz extends super.Baz {
    override def bar = Set("c", "d")
  }
  override object Baz { 
    def apply() = new Baz
  }
}

使用此(new SubFoo).Baz().bar == Set("c", "d")。但是,如果您的子类实例被键入为Foo,则可能会遇到运行时类强制转换异常,如此错误:SI-6525

原始答案:

你需要在Foo类中有一个可以返回Bar子类的可覆盖工厂方法。然后在您的Foo子类中,返回一个Bar子类,并重写bar方法。例如:

class Foo {
  trait Bar {
    def bar = Set("a", "b")
  }

  def createBar = new Bar {}
}

class SubFoo extends Foo {
  override def createBar = new Bar { override def bar = Set("c", "d") }
}

scala> var foo: Foo = new Foo
foo: Foo = Foo@5ea0e5b9

scala> foo.createBar.bar
res15: scala.collection.immutable.Set[String] = Set(a, b)

scala> foo = new SubFoo
foo: Foo = SubFoo@7f8d5474

scala> foo.createBar.bar
res16: scala.collection.immutable.Set[String] = Set(c, d)

答案 1 :(得分:0)

您可以尝试创建父类是原始Baz的新类。然后覆盖bar的定义:

val f = new Foo { 
  class Baz2 extends Bar { override def bar = Set("c") } 
  object Baz2 { 
   def apply() = new Baz2(); 
  }
}

这将为您提供一个新条目:f.Baz2().bar,它将为您提供Set(“c”)。您仍然可以访问原始Bar特征的成员。

据我所知,你无法覆盖内部类的对象。因此,很难在该课程中产生新的特征。