私は、部分的にScalaで、一部は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*/
}
問題があります。if '1'と書かれた行は上のコードのとおりですが、コンパイラはoverriding variable subject in class AbstractTest of type ISubject; value subject has incompatible type
という文句を言います。 1行目の型名annotation : CSubject
とキーワードoverride val
を削除した場合、そのエラーは消えますが、もう1行目は「2」に表示されます:value b is not a member of ISubject
私はこれらのエラーが何を言っているのか、そしてコンパイラがこれらの問題をどのように考えているのかを理解しています。私が理解できないことは、Javaの場合と同じように動作を取得する方法です。クラスのインターフェイスメンバーを実装する場合、インターフェイスを実装する任意の種類のクラスで初期化することができます。 Scalaでこれを行う方法は何ですか?
更新日: Scalaでこのような構造を実現することは不可能なのは本当ですか?私がそれをしたいのは、AbstractTest
には、サブジェクトのISubject
を扱うメソッドと、subject
をオーバーライドし、それをより狭いクラスインスタンスとして定義する子クラスがあり、そのクラスに固有のメソッドを実装する必要があるからです。それと同時に、私はAbstractTest
がすべてsubject
について扱い続けたいと思っており、それはそのインターフェイスISubject
を通して扱われている間に処理することができます。
あなたの質問に答えるために、私が達成しようとしているのは、 'Subject'のコア処理を' AbstractTest'クラスに入れることです。しかし、そのクラスの子は、それをより狭いクラスのインスタンスに初期化し、その特定の子クラスに適した、より多くのメソッドを定義する必要があります。同時に、AbstarctTestクラスで定義されているコアメソッドは、より広いISオブジェクトとして 'subject 'を扱うという使命を果たすことができるはずです。 – noncom
私が理解する限り、Java変数では無効にならず、むしろ隠されてしまいます。 – noncom
AbstractTestクラスは、generateParticularSubject()メソッドの宣言から続くCSubject型を認識しています。なぜ、 'AbstractTest.subject'をISubjectではなくCSubjectとして宣言してください。第二に、あなたが正しく言うように、Javaのメンバーフィールドはオーバーライドされたものより薄暗くなります。もしあなたがそのルートに行きたいなら、 'AbstractTest.subject'は実際に私的な可視性で宣言され、' Test'は独自の 'private val subject '狭いタイプの。 – elk