I have the following code, partly in Java, partly in 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();
}
}
Scala:
object Test extends AbstractTest {
override val subject: CSubject = generateParticularSubject() /*1*/
subject.b() /*2*/
}
The issue is: if the line marked ‘1’ is as it is in the code above, the compiler complains that overriding variable subject in class AbstractTest of type ISubject; value subject has incompatible type. If I remove the type annotaion : CSubject in line ‘1’ and the keywords override val, that error disappears but another one appears at line ‘2’: value b is not a member of ISubject.
I understand what these errors say and the way the compiler thinks getting these problems. What I do not understand, is how to get the behavior same as in Java, where implementing an interface member of a class, it is possible to initialize it with any kind of class that implements the interface. What is the way to do this in Scala?
UPDATE: Is it truth that it is impossible to realize such a construct in Scala? The reason why I want to do that is because AbstractTest contains methods that deal with ISubject side of the subject and the child classes who should override subject and define it as a narrower class instance, must implement methods specific to that class. At the same time I want AbstractTest to keep handling all that regards subject and can be handled while it is treated through it’s interface ISubject.
The Java field
subjectis mutable, therefore it cannot be overridden in Scala using aval. Also, being assignable, it wouldn’t be safe to vary it co-variantly.You can fix your code by making
subjectan abstract method. That can be overridden covariantly with aval, as you are doing in your Scala code.