2009-08-31 4 views
0

は私のコードのJavaオーバーライド説明はここで

class Glyph { 
    void draw() { System.out.println("Glyph.draw()"); } 
    Glyph(int i) { 
    System.out.println("Glyph() before draw()"); 
    draw(); 
    System.out.println("Glyph() after draw()"); 
    } 
} 

class RoundGlyph extends Glyph { 
    private int radius = 1; 
    RoundGlyph(int r) { 
     super(r); 
    radius = r; 
    System.out.println("RoundGlyph.RoundGlyph(), radius = " + radius); 
    } 
    void draw() { 
     System.out.println("RoundGlyph.draw(), radius = " + radius); 
    } 
} 

public class PolyConstructors { 
    public static void main(String[] args) { 
    new RoundGlyph(5); 
    } 
} 

出力です:

Glyph() before draw() 
RoundGlyph.draw(), radius = 0 
Glyph() after draw() 
RoundGlyph.RoundGlyph(), radius = 5 

なぜサブクラスRoundGlyphのdrawメソッドを呼び出し、スーパークラスGlyphのコンストラクタはありますか?どのようにスーパークラスのコンストラクタからスーパークラスの描画メソッドを呼び出すことができますか? CTORから非プライベートまたは非静的メソッドの呼び出しは、呼び出し元になりますので、私はこれを試してみましたが、それはうまくいきませんでした....

答えて

3

なぜサブclasssのスーパー呼び出しdrawメソッドのコンストラクタ

これは、メソッドの動作をオーバーライドする方法です。サブクラスが親(または祖父母など)と同じシグネチャを持つメソッドを実装している場合、その祖先の1人がsuper.を指定せずにそのメソッドを呼び出すと、サブクラスのバージョンが呼び出されます。私は、サブクラスのバージョンとは対照的に、方法のバージョンを呼び出して指定する方法がありませんスーパー

のコンストラクタからスーパーのメソッドを呼び出すことができますどのように

クラスを設定するために必要なもの以外のコンストラクタで作業しないでください。

3

それは、ctorsから非プライベートまたは非静的メソッドを呼び出すために悪い習慣ですあなたの場合と同じように、サブタイプのメソッドです。 これを行わずに、アプリケーションの設計を変更しないでください。

+0

はい私は今は知っていましたが、どのように、なぜこれがこのように機能しているのか不思議でした。 –

1

できません。すべてのメソッドはJavaでは仮想メソッドであり、継承階層でどのメソッドを実行するかを指定することはできません。唯一の例外は、サブクラスが自身をオーバーライドしてもサブクラスが親のメソッドを呼び出すことができることです。

メソッドをオーバーライドできないようにするには、final(またはprivate)として宣言します。

+0

+1はJavaのすべてのメソッドが仮想であることに注意してください。私は他の答えのどれもがそれを言及しなかったことを驚いた。 – Powerlord

1

あなたがサブクラス型のオブジェクトを作成しているので、基本クラスのコンストラクタは、サブクラスdraw()メソッドを呼び出しています。これはどのように動作するはずです。サブクラスのメソッドは、クラスローダーによってロードされます。コンストラクターが呼び出されるときではなく、コンストラクターによって実行可能な状態になっています。詳細については、the relevant section of the JLSを参照してください。

あなたがしようとしている方法で、サブクラスのインスタンスから基底クラスdraw()メソッドを呼び出すことはできません。 ではなく、のサブクラスのメソッドをオーバーライドするか、拡張する代わりにGlyphをカプセル化するようにデザインを変更する必要があります。

2

これはコンストラクタのデザインが悪いとの回答に同意します。しかし、基底クラスのメソッドを基底クラスから呼び出す必要がある場合は、オーバーライドされていないメソッドにコードを抽出する必要があります。インスタンス化されたサブクラスオブジェクトは、常にオーバーライドされたメソッドを実行します。

class Glyph { 
    void draw() { 
     doDraw(); 
    } 

    private void doDraw() { 
     System.out.println("Glyph.draw()"); 
    } 

    Glyph(int i) { 
     System.out.println("Glyph() before draw()"); 
     doDraw(); 
     System.out.println("Glyph() after draw()"); 
    } 
} 
関連する問題