我有下面的代码,这部分在Java中,部分在斯卡拉:斯卡拉:继承接口成员初始化
的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
。如果我删除'1'行中的类型注释: CSubject
和关键字override val
,该错误消失,但另一个出现在行'2':value b is not a member of ISubject
。
我明白这些错误的含义以及编译器认为如何解决这些问题的方式。我不明白的是,如何获得与Java中相同的行为,在该类中实现类的接口成员,可以使用任何实现该接口的类来初始化它。在Scala中如何做到这一点?
更新:难道在Scala中实现这样的构造是不可能的吗?之所以我想这样做,是因为AbstractTest
包含处理主题的ISubject
一侧的方法以及应重写subject
并将其定义为较窄类实例的子类,必须实现特定于该类的方法。同时,我希望AbstractTest
继续处理所有关于subject
的问题,并且可以通过它的接口ISubject
对其进行处理。
回答你的问题,我可以说,我试图达到的目标是将'subject'的一些核心处理放到'AbstractTest'类中。但是该类的孩子必须能够将其初始化为更窄的类实例,并定义更多的方法来处理它,这也适合于特定的子类。同时,'AbstarctTest'类中定义的核心方法应该仍然能够完成将'subject'视为更广泛的'ISubject'的任务。 – noncom 2012-02-08 12:18:09
据我所知,在Java变量不会超过,而是他们得到阴影。 – noncom 2012-02-08 12:19:00
AbstractTest类意识到CSubject类型 - 从generateParticularSubject()方法的声明开始 - 为什么不将'AbstractTest.subject'声明为CSubject而不是ISubject?其次,正如你所说的,Java中的成员字段比被覆盖的字段盖过了阴影,如果你想要走这条路线,那么'AbstractTest.subject'应该用私有可见性来声明,'Test'应该有它自己的'private val subject更窄的类型。 – elk 2012-02-08 12:24:33