ScalarObject というクラスと、ScalarObject を継承する Variable というクラスがあります。常に false を返す ScalarObject と、それらを表す文字列が等しい場合に true を返す Variable に「equals」を定義しました。
次のコード:
ScalarObject a1 = new Variable("a");
ScalarObject a2 = new Variable("a");
System.out.println(a1.equals(a2));
false を返します。次のコード:
Variable a1 = new Variable("a");
Variable a2 = new Variable("a");
System.out.println(a1.equals(a2));
true を返します。次のコード:
ScalarObject a1 = new Variable("a");
ScalarObject a2 = new Variable("a");
System.out.println(((Variable) a1).equals(((Variable) a2)));
も true を返します。問題は、ScalarObject から派生した他のクラスもあるということです。ScalarObject 型で宣言されているプログラム オブジェクトの一部がありますが、それから派生した任意のクラスのメンバーになる可能性があるため、ScalarObject オブジェクトを派生型にキャストすることはできません。たとえば、私のプログラムの一部には次のものがあります。
protected void neighbor_simplify(LinkedList<ScalarObject> L, char op) {
...
if(n1 instanceof Variable && n2 instanceof Variable) {
System.out.println(((Variable) n1).getSymbol());
System.out.println(((Variable) n2).getSymbol());
}
if(n1.equals(n2)) { // x+x=2*x
System.out.println("B ");
プログラムは "x" を 2 回出力しますが、"B" は出力しません。変数 n1 と n2 は、連結リスト "L" から取得されます。プログラムが「Variable.equals()」ではなく「ScalarObject.equals()」(常に false を返す) を呼び出していると思われます。n1 と n2 を Variable 型にキャストする際の問題は、n1 と n2 が ScalarObject から派生した他のクラスのインスタンスになる可能性があることです。基本クラスとして宣言されている場合でも、プログラムが基本クラスではなく派生クラスからメンバーを呼び出すようにするにはどうすればよいですか?
Windows Vista で NetBeans 6.9.1 を使用しています。
Web で検索すると、http: //wiki.answers.com/Q/Can_a_base_class_access_members_of_a_derived_class にたどり着きました。Java では、@Override 表記が使用されている場合、基本クラスは派生クラスのメンバーにアクセスできると記載されています。ただし、 @Override を Variable.equals() に追加すると、おそらくシグアチャが異なるため、メソッドがスーパータイプのメソッドをオーバーライドしないというエラーが表示されました。ScalarObject.equals() は ScalarObject 型の引数を取り、Variable.equals() は Variable 型の引数を取ります。