2011-06-28 18 views
3

私はクラスを拡張し、このクラスのメソッドをオーバーライドすると言う。なぜ、私の新しいクラスのコンストラクタからオーバーライドされたメソッドを呼び出すのが悪い習慣ですか?Java継承質問

+1

なぜそれは悪い習慣だと思いますか?それはおそらく状況に依存します... –

+2

Netbeansはそれに下線を付け、私に警告を与えます – user489041

+0

OK、警告は何ですか? – gatkin

答えて

12

オーバーライド可能なメソッドをコンストラクタから呼び出さない主な理由は、サブクラスがクラスを半構築状態で見ることができるということです。これはセキュリティ上のリスクかもしれませんが、発生するのを待っているバグです。続きを読むhere

+0

リンクのための+1 ...ついに私はビーチに行くときに読む何か! – SJuan76

5

コンストラクタで作業を行うのは悪い習慣です。オブジェクトの依存関係を取得して割り当てるだけです。

3

あなたのクラスから継承し、コンストラクタに依存する動作を変更することができます。

これは、あなたがその機能が何をしようとしているのかわからないことを意味します。

3

結果のクラスのインスタンスが矛盾した状態になる可能性があるためです。ここに具体例があります。

public class Foo { 
    private int number; 

    public Foo() { 
     number = 42; 
     multiplyNumber(); 
    } 

    public void multiplyNumber() { 
     number = number * 2; 
    } 

    public int getNumber() { 
     return number; 
    } 
} 

public class Bar extends Foo { 

    private int number; 

    public Bar() { 
     multiplyNumber(); 
    } 

    @Override 
    public void multiplyNumber() { 
     number = number * 3; 
    } 
} 

public class FooBar { 

    public static void main(String[] args) { 
     Foo foo = new Foo(); 
     Foo bar = new Bar(); 
     System.out.println("Foo number 1 = " + foo.getNumber()); // Returns 84 
     System.out.println("Foo number 2 = " + bar.getNumber()); // Returns 42; 
    } 
} 

私のマシン上でデバッグを走る、barは実際には、コンストラクタでmultiplyNumber()メソッドを呼び出すことはありません。それはちょうどスキップされます。結果として、オブジェクトは期待値がnumberにありません。

コンストラクタは単純な生き物でなければなりません。非常に複雑なものを置かないことをお勧めします。

1

コンストラクタでオーバーライド可能なメソッドを呼び出すとします。再度サブクラス化して再度オーバーライドします。 2番目のサブクラスは、最初のサブクラスが完全に初期化されているとみなされる作業を中断し、破損した状態にすることがあります。

コンストラクタでの作業です。あなたは仕事をすることができます。通常は、あなたのオブジェクトを初期化するために必要な仕事のタイプでなければなりません。

継承を避けるために、コンストラクタの処理をメソッドに分割する場合は、可視性修飾子を使用して、すべての作業が構築中のクラスに対してローカルになるようにします。