Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 有可能超越内在特质的成员吗?_Scala_Inheritance_Inner Classes_Overriding - Fatal编程技术网

Scala 有可能超越内在特质的成员吗?

Scala 有可能超越内在特质的成员吗?,scala,inheritance,inner-classes,overriding,Scala,Inheritance,Inner Classes,Overriding,在扩展外部类时,是否可以重写内部特征的成员?像 class Foo { trait Bar { def bar = Set("a", "b") } class Baz extends Bar object Baz { def apply() = new Baz } } 我可以创建Foo的实例f,以任何形式,例如f.Baz().bar==Set(“c”,“d”) 澄清:类Foo是给定的,我无法更改它。它调用了Baz(),因此我也无法更改它。因此,可能无法在B

在扩展外部类时,是否可以重写内部特征的成员?像

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

  class Baz extends Bar
  object Baz {
    def apply() = new Baz
  }
}
我可以创建
Foo
的实例
f
,以任何形式,例如
f.Baz().bar==Set(“c”,“d”)

澄清:类
Foo
是给定的,我无法更改它。它调用了
Baz()
,因此我也无法更改它。因此,可能无法在
Bar
Baz

编辑:

根据您的说明,您要做的似乎是覆盖对象
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
  }
}
使用此
(新的subfo).Baz().bar==Set(“c”,“d”)
。但是,如果您的子类实例被类型化为
Foo
,则可能会出现运行时类强制转换异常,如以下错误:

原始答案:

在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)

您可以尝试创建一个新类,其父类是原始Baz。然后替代条形图的定义:

val f = new Foo { 
  class Baz2 extends Bar { override def bar = Set("c") } 
  object Baz2 { 
   def apply() = new Baz2(); 
  }
}
这将为您提供一个新条目:
f.Baz2().bar
,它将为您提供Set(“c”)。您仍然可以访问原始酒吧的成员


据我所知,您不能重写内部类的对象。因此,很难在该类上生成新的特征。

问题是
Foo
的实现实例化了
Baz
,因此它不会注意到不同的子类,我不确定我是否遵循。。。你指的是哪一个子类?在上面的实现中,您获得了所有原始Baz,但覆盖了一个特定的方法。你能澄清你需要做什么吗?问题是,
Foo
是一个给定的,我没有设计它(它实际上是Scala编译器框架的一部分),也许你可以澄清一些约束。我已经展示了如何在扩展外部类时对内部特性进行子类化。然而,要使用子类内部特征,您需要实例化它。如果您不能用新特性覆盖实例化原始特性的代码,那么您就无能为力了。但这实际上与这是一种内在特征这一事实无关。