我有以下代码,部分在 Java 中,部分在 Scala 中:
Java:
public interface ISubject {
public void a()
//...
}
public class CSubject implements ISubject {
public void a() { /*...*/ }
public void b() { /*...*/ }
//...
}
public abstract class AbstractTest {
ISubject subject;
//...
public CSubject generateParticularSubject() {
return new CSubject();
}
}
斯卡拉:
object Test extends AbstractTest {
override val subject: CSubject = generateParticularSubject() /*1*/
subject.b() /*2*/
}
问题是:如果标记为“1”的行与上面的代码相同,编译器会提示 overriding variable subject in class AbstractTest of type ISubject; value subject has incompatible type
.如果我删除类型注释 : CSubject
在“1”行和关键字 override val
,该错误消失,但另一个错误出现在第“2”行:value b is not a member of ISubject
.
我理解这些错误的含义以及编译器解决这些问题的方式。我不明白的是,如何获得与 Java 相同的行为,在 Java 中实现一个类的接口(interface)成员,可以用任何实现该接口(interface)的类来初始化它。在 Scala 中有什么方法可以做到这一点?
更新:在 Scala 中不可能实现这样的结构是真的吗?我之所以要这样做是因为 AbstractTest
包含处理 ISubject
的方法主题的一侧和应该覆盖的子类subject
并将其定义为更窄的类实例,必须实现特定于该类的方法。同时我要AbstractTest
继续处理所有关于 subject
的事情并且可以在通过其界面处理时进行处理 ISubject
.
最佳答案
Java 字段 subject
是可变的,因此不能在 Scala 中使用 val
覆盖它。此外,由于是可分配的,因此协变地改变它是不安全的。
您可以通过使 subject
成为抽象方法来修复您的代码。这可以用 val
协变地覆盖,就像您在 Scala 代码中所做的那样。
abstract class AbstractTest {
public abstract ISubject subject();
//...
public CSubject generateParticularSubject() {
return new CSubject();
}
}
关于java - Scala:继承接口(interface)成员初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9192708/