2009-07-28 24 views
1

私は、このセットアップに似た何かをお持ちですか?Javaの継承質問

+0

毎回ベースのリンゴを返すか、ベースのリンゴを毎回返すかどうかわからない理由> – Janusz

+0

実行時に問題をコンパイルして再現する最小限のコード例を投稿する必要があります。あなたがそれをするならば、あなたはおそらくすでに問題が何であるか気づくであろう。 –

+0

回答者のためのThx、この場所は本当に素晴らしいです!私のJavaコードは実際にはうまくいきました...上の例はイラストレーションのためのものでしたが、実際にコンパイルするコードを投稿する次回の努力をします。問題は実際には、AJAXリクエストを作成していたjavascriptにありました。リクエストを送信する前にフォームのシリアル化に失敗しました...とにかく、私は本当にすべての答えからかなり多くを学んだのです! :) – hdx

答えて

6

まず:

if (b instanceof Extended){ 
    b = (Extended) b; 
} 

は絶対に何もしません。あなたは基本的には何も言わないb = bと言っています。あなたは参照を変更していません。

第2に、getApple()は常に動的にバインドされ、サブクラスが本当にベースクラスを拡張しているため、メソッドが本当にオーバーライドされている場合は常に「拡張リンゴ」を呼び出す必要があります。

基本的にあなたが正しいgetApple()行動を達成するために、何をする必要があるか:

  • かの句を削除します。それは何もしません。
  • クラスが基本クラスを実際に拡張していることを確認してください
  • getApple()メソッドが基本クラスメソッドをオーバーライドしていることを確認してください。
+0

私は彼が絶対に彼のbが本当に拡張されていると判断するためにそれを使用していると仮定します。 –

+3

しかし、それでも何も変わりません... if節は何の効果もありません。 –

+0

if節は何もしません。javaの "casts"では、キャストが許可されていることを確認します。例えば、Cのように実際にキャストはしません。 –

0

その動作を取得する唯一の方法は、拡張クラスでsuper.getApple()を返すことです。これは、最初は上書きしないのと実質的に同じです。これが助けることができる唯一の方法は、あなたが何を返すかを決定するために引数を渡す場合です。良いデザインだと言っているわけではありません...

Yuvalが言ったように、キャストはオブジェクトに何もしません。

4

書かれているように、あなたのコードはコンパイルされないため、あなたの問題は他の場所にあると思います。あなたのリターンステートメントの最後にセミコロンはありません。むしろ、}の後に表示されます。他の問題(おそらくあなたのサブクラスのgetApple()のスペルミス)がある可能性がありますが、あなたの新しいクラスはまだコンパイルされていないので、古いクラスファイルを使用しています。

このコードは動作します:

class Base { 
    public String getApple() { return "base apple"; } 
} 
class Extended extends Base { 
    public String getApple() { return "extended apple"; } 
} 
public class Test { 
    public static void main(String[] args) { 
    Base b = new Extended(); 
    System.out.println(b.getApple()); 
    } 
} 

コンソール:すべての

#javac Test.java 
#java Test 
extended apple 
+0

Javaのすべてのメソッドが仮想であるため、これは機能します。 – Powerlord

+0

C++の観点からは正しいです。より正確には、Javaのすべてのメソッド呼び出しは実行時に動的にバインドされます。 –

1

まず、ブロックが必要になることはありません場合に。それは基本的にノーオペレーションです。

第2に、これは実際のコードではなく、コンパイルされていないためです。返信文の後にセミコロンがありません。

実際のコードに2つのgetAppleメソッドのシグネチャを異なるようにする誤植があると思われます。つまり、Extendedには、Baseから継承されたものと、異なる署名を持つものの2つのメソッドがあります。 Base.getAppleメソッドのシグネチャを呼び出すので、常にその動作を取得しています。あなたの投稿されたコードはあなたが記述した問題を示さないので、これは推測に過ぎません。

1

Yuvalあなたのキャストがifブロックのキャストが効果がないというのは正しいですか?あなたはifであなたの最後のステートメントを組み合わせてみてください:

if (b instanceof Extended) 
{ 
    // Prints "extended apple" if reached. 
    System.out.println(((Extended)b).getApple()); 
} 
+0

は全く必要ありません。 (拡張)にキャストしなくても、「拡張リンゴ」が印刷されます。 –

+0

彼のコードコメントで報告した動作は、他の何かの結果であると思いますか? –

0

あなたはinfo.getForm()から返されるインスタンスを構築しているものを調査する必要があります。ベース抽象化をインスタンス化されないようにすると、構築がどこで起きているかが素早くわかります。

1

サブクラスのメソッドに@Overrideを追加し、再コンパイルします。これは、実際にあなたが思っている方法を上書きしていないかどうかを調べるのに役立ちます。

すなわち

public class Base { 
    public String getApple() {return "base apple";} 
} 

public class Extended extends Base{ 
    @Override 
    public String getApple() {return "extended apple";} 
} 
0

あなたは、あなたの質問に提供し、あなたのコード例では、正確にあなたが使用しているコードと一致しますか?私が尋ねる理由は、公共のFIELD メソッドの代わりに、フィールド公共のオブジェクトにアクセスするときに、あなたが記述している動作が起こるということです。例えば

public class BaseClass { 
    public String baseField; 

    public BaseClass() { 
     baseField = "base"; 
    } 

    public String getBaseField() { 
     return baseField; 
    } 
} 

public class SubClass extends BaseClass { 
    public String baseField; 

    public SubClass() { 
     baseField = "sub"; 
    } 

    public String getBaseField() { 
     return baseField; 
    } 
} 

public class MainClass { 
    public static void main(String[] args) { 
     BaseClass baseObject = new BaseClass(); 
     SubClass subObject = new SubClass(); 
     System.out.println(baseObject.getBaseField()); 
     System.out.println(subObject.getBaseField()); 
     System.out.println(baseObject.baseField); 
     System.out.println(subObject.baseField); 
     System.out.println(((BaseClass)subObect).getBaseField()); 
     System.out.println(((BaseClass)subObect).baseField); 
    } 
} 

は、プリントアウトします:あなたがメソッドを呼び出すと、JVMは、継承階層の最下部に開始し、適切なメソッドを呼び出します

base 
sub 
base 
sub 
sub 
base 

フィールドを代わりに参照すると、値を解決するためにクラス階層を歩く代わりにポインタのクラスが使用されます。フィールド参照の動作は、表示されているものと一致します。そのため、私は明確化/検証を求めています。