我用几种不同的方式搜索了这些......但还没有找到明确的答案。
class Foo1 { }
class Foo2 extends Foo1 { }
class Bar1 {
var foo: Foo1 = null
}
class Bar2 extends Bar1 {
var foo: Foo2 = null // <-- compiler error
}
错误说:“在类型为test.Foo1的类Bar1中覆盖变量foo;变量foo需要`override'修饰符”但您也不能覆盖var。
在C#中,你可以使用像这样的新关键字
class Foo1 { }
class Foo2 : Foo1 { }
class Bar1
{
public Foo1 foo = null;
}
class Bar2 : Bar1
{
public new Foo2 foo = null;
}
是否可以在Scala中执行此操作?
编辑 - 添加了另一个C#示例来说明我为什么要这样做。
class Foo1 { }
class Foo2 : Foo1 { }
class Bar1
{
public Foo1 Foo { get { return _foo; } }
protected Foo1 _foo;
public Bar1(Foo1 foo) { _foo = foo; }
}
class Bar2 : Bar1
{
public new Foo2 Foo { get { return _foo; } }
protected new Foo2 _foo;
public Bar2(Foo2 foo) : base(foo) { _foo = foo; }
}
当然,在真正的应用程序中,类和许多成员的方式更复杂,层次结构更深入。
简而言之,它对我的作用是它允许我在我的类层次结构中的任何地方使用foo变量而不必使用丑陋的演员表 - 如果我只在声明的单个foo中使用了Bar1班。
谢谢!
答案 0 :(得分:2)
您似乎正在寻找var
属性的协方差。这不会编译,因为它不合理:
class Foo1
class Foo2 extends Foo1 {
def moo = 42
}
class Foo3 extends Foo1
class Bar1 {
var foo: Foo1 = null
}
class Bar2 extends Bar1 {
var foo: Foo2 = null // Let's suppose this compiles
}
val bar2: Bar2 = new Bar2
val bar1: Bar1 = bar2
bar1.foo = new Foo3
bar2.foo.moo
在最后一行,您在.moo
的实例上调用Foo3
(它没有实现此类方法),但编译器无法告诉您这一点,因为{{1} }应该是bar2.foo
。
在Foo2
然而它编译:
val
更新
经过一些测试和reading this后,我在C#代码中理解的是,class Bar1 {
val foo: Foo1 = new Foo1
}
class Bar2 extends Bar1 {
override val foo: Foo2 = new Foo2
}
实例中确实有2个字段。当被视为Bar2
时,Bar1
引用x.foo
中的字段,并且被视为Bar1
,Bar2
指的是Bar2中的属性。它们的类型甚至它们的性质(方法/字段/类型)可以完全不相关。我无法想到Scala中的任何类似内容。但如果我更正确,您也可以使用x.foo
Bar2
的其他名称。
更新2
如果永远不会重新分配foo
,则可能是您想要的代码:
foo
答案 1 :(得分:2)
这通常表示为类型参数或类型成员。
例如,集合跟踪其基础&#34;表示&#34;或实施:
https://github.com/scala/scala/blob/v2.11.4/src/library/scala/collection/GenSeqLike.scala#L33
它出现在以下的地方:
但是成员隐藏机制解决的另一个问题是脆弱的类型层次结构。必须为继承设计类(Effective Java)。因此,一个类可以在不考虑与客户端(包括子类)的兼容性的情况下发展的概念具有误导性。
由于私有成员的继承(或不是),Scala中出现了这种情况。我无法随意找到讨论,但in this issue它被称为weird "private members aren't inherited" change
。你可能会去,&#34;这有什么奇怪之处?&#34;
This issue可能是伞问题或元bug。
这是令人烦恼的案例:
scala> class A { val v: Int = 42 }
defined class A
scala> class B extends A { private val v: String = "42" }
<console>:8: error: overriding value v in class A of type Int;
value v has weaker access privileges; it should not be private
class B extends A { private val v: String = "42" }
^
有些人主张加强隐私权。