2013-02-01 12 views
6

オーバーライドコンストラクタと大きく混乱しています。コンストラクタをオーバーライドすることはできません私はグーグルでそれを検索するとき、私はこれを実行するとコンストラクタのオーバーライド

In Super constructor 
In Sub.test() 
In Sub constructor 
In Sub.test() 

PLSは、サブクラスで試験方法を注意して、私の質問は、私は結果を

public class constructorOverridden { 

    public static void main(String args[]) { 
     Sub sub = new Sub(); 
     sub.test(); 
    } 
} 

class Super { 
    Super() { 
     System.out.println("In Super constructor"); 
     test(); 
    } 

    void test() { 
     System.out.println("In Super.test()"); 
    } 
} 

class Sub extends Super { 
    Sub() { 
     System.out.println("In Sub constructor"); 
    } 

    void test() { // overrides test() in Super 
     System.out.println("In Sub.test()"); 
    } 
} 

得ている何を得る結果であります実行される。スーパークラスのコンストラクタがオーバーライドされていることを示していますか?それが正しいかどうか?

答えて

19

コンストラクタは多態性ではありません。を無効にすると、のアサーションはありません。 新しいコンストラクターをサブクラスに作成し、各サブクラスコンストラクターは、スーパークラスコンストラクターに(場合によっては間接的に)連結する必要があります。明示的にコンストラクターに連結しないと、パラメーターのないスーパークラスコンストラクターへの暗黙の呼び出しが、サブクラスコンストラクター本体の先頭に挿入されます。

のメソッドをにオーバーライドしました。オブジェクトは、スーパークラスのコンストラクタの実行時を含め、最初から「最終型」の権利を持っています。したがって、SuperコンストラクタコードにgetClass()を印刷すると、出力にはまだSubが表示されます。その結果、Subコンストラクタがまだ実行されていなくても、オーバーライドされたメソッド(つまりSub.test)が呼び出されます。

これは根本的に悪い考えです、そしてあなたは、ほとんどの場合、潜在的にオーバーライドされたコンストラクタのメソッド呼び出しを避ける必要があります - サブクラスのコードは、それができることを認識しているように、」(それがケースになるだろうということ非常に明確にまたは文書を適切に初期化された変数などに依存する)。

+0

次に、「コンストラクタでオーバーライドされたメソッドを呼び出す」ことを回避するには、どのようなアプローチを使用する必要がありますか?私が達成しようとしていたのは、抽象メソッドinit()、build()、そしてfill()を呼び出すスーパークラスコンストラクタの基本的な流れです。そのため、すべてのサブクラスで同じフローを実行する必要があります。 – Akshat

+0

@Akshat:「文書は非常にはっきりと」分類されているようです。通常、これを中心にいくつかの設計方法がありますが、一般的なレシピを与えるのは難しいです。 –

+0

あなたがそれらの方法へのリンクを与えることができれば、それは素晴らしいことでしょう! – Akshat

3

コンストラクタの最初の暗黙の行は、Super()の呼び出しです。だからあなたはその結果を得る。

3

これは間違いありません。サブクラスをインスタンス化するときは、スーパークラスのコンストラクタが最初に呼び出され、次に階層の各コンストラクタが呼び出されます。

上記の例では、スーパークラスコンストラクタはオーバーライドされたメソッド(test())を呼び出します。これは機能しますが、サブクラスのコンストラクタが呼び出されておらず、サブクラスが完全に初期化されていないため、潜在的に危険です。このため、コンストラクタでオーバーライドされた(またはオーバーライド可能な)メソッドを呼び出すことは適切ではありません。

2

スーパークラスのコンストラクタをオーバーライドしておらず、コンストラクタをオーバーライドできないため、オーバーロードすることができます。

子クラスを作成すると、スーパークラスが最初にインスタンス化され、次にサブクラスがインスタンス化されます。そのような子供は親なしで存在することはできません

コンパイラは自動的にスーパークラスコンストラクタをサブクラスコンストラクタから呼び出します。

Sub() { 
    super(); 
    System.out.println("In Sub constructor"); 
} 
4

コンストラクタが構築するクラスの名前によってコンストラクタが呼び出されるため、コンストラクタをオーバーライドすることはできません。どのように同じコンストラクタでいくつかの異なるクラスを作成できますか?また、子クラスは親からコンストラクタを継承しません。

親のコンストラクタは、いくつかの重要な初期化を行う場合は、スーパーを使用して、子コンストラクタから呼び出すことができます。

class Err extends Throwable { 
    Err(String message) { 
     super(message); // Call the constructor of Throwable. 
     .. 

親クラスのコンストラクタも常に呼ばれています。自分でanyを呼び出さない場合は、派生クラスのコンストラクターを入力する前に、パラメーターのないコンストラクターが自動的に呼び出されます。親にパラメータのないコンストラクタがなく、anyを呼び出さない場合は、コンパイル時エラーが報告されます。

関連する問題