2011-10-18 12 views
1

私は最終的なキーワードのいくつかの練習を準備しています。サブクラスでオーバーライドできないメソッドを定義するために使用されます。メソッドをオーバーライドしない単純な実世界の例?

しかし、私は、サブクラスでメソッドがオーバーライドされないようにするため、実際の良いシンプルな実例を見つけるのに問題があります。

ヒント

+2

を私が持っていた場合私が 'java-docsを' grep'して、標準APIでの使用を見つけた時です。 – aioobe

+0

'Object.getClass()'メソッドはfinalです。 –

答えて

2

equals()の実装では、抽象クラスではないメソッドをfinal修飾子でマークする必要があります。この文は、簡単に例(標準ライブラリから実際のコード)によって証明することができます。

public class Date { 

    private transient long fastTime; 

    .... 

    public long getTime() { 
     return getTimeImpl(); 
    } 

    .... 

    public boolean equals(Object obj) { 
     return obj instanceof Date && getTime() == ((Date) obj).getTime(); 
    } 
} 

public class Timestamp extends java.util.Date { 

    public boolean equals(java.lang.Object ts) { 
     if (ts instanceof Timestamp) { 
     return this.equals((Timestamp)ts); 
     } else { 
     return false; 
     } 
    } 

    public boolean equals(Timestamp ts) { 
     if (super.equals(ts)) { 
      if (nanos == ts.nanos) { 
       return true; 
      } else { 
       return false; 
      } 
     } else { 
      return false; 
     } 
    } 
} 

のequals()契約に違反していることを意味する:

date.equals(timestamp) == true 

しかし

timestamp.equals(date) == false 
2

最終のメソッドは、コンパイラによってインライン化されて、サブクラスになることがあり、小さなパフォーマンス上の利点があります。

サブクラスが独自のメソッド定義を提供しないようにする場合の例として、メソッドの定義がオブジェクトの耐久性やシステムのパフォーマンスにとって重要な場合は常にfinalでなければなりません。

コンストラクタから呼び出されるメソッドは、堅牢なクラス定義を確実にするために、通常は最終的なものである必要があります。

実世界の例は、常に複数の開発者環境になります。あなたがクレジットカード情報を扱う会社で働いていて、重要なことを行うjavaクラスを持っている場合、誤って重要なメソッドを上書きしてしまうインターンが欲しくないので、他の開発者でもできないような方法でシステムを構築するそれは安全ではない。

最終的なクラスと最終フィールドについても忘れてください!

2

オブジェクトの状態の一部が変更されたことをオブジェクトに通知するようにクラスを設定することができます。あなたのクラスをサブクラス化する人々が、この状態がどのように変化するかを上書きできるようにするが、これらのイベントは送信されないようにする。

public class Womble { 
    public String fluff; 

    // notify listeners that the value of 'fluff' is changing 
    private void onFluffChanging() { 
     //… 
    } 

    // Others can override this method 
    protected void setFluffImpl(String value) { 
     fluff = value; 
    } 

    // But not this one, so the notification always gets sent 
    public final void setFluff(String value) { 
     onFluffChanging(); 
     setFluffImpl(value); 
    } 
} 

一般的に、クラスの動作がサブクラスによって「削除」されないようにするには、finalを使用します。また、コードの意図しない使用を防止するために、デフォルトですべてをfinalにする方が好きです。finalでないクラスとメソッドは、明示的にサブクラス化するクラスとメソッドだけです。後者は、再利用されるコードを作成する場合、特にそのクラスを多く継承して再利用されるコードを作成する場合に非常に便利です。

2

ここで他の回答と相殺するために、実際の使用では、クラスを将来どのように使用する必要があるかを正確に予測することは困難です。何も変えてはいけないと感じているので、finalをあなたのコードに振りかけると、予期しなかった方法でそのコードを使用している人の将来の不満に加えて、finalはクリエイティブ開発者が常に邪魔することがあります。それはあなたが彼/彼女にそのように誘惑したいと思っていることのどれだけの質問です。そして、それになるならば、その人本当にが彼または彼女がやっていることを知っているほうがよいでしょう。

2

Template Methodパターンを使用するフレームワークやライブラリコードの例があります。そう例えば、SwingWorkerに、​​とrun()を含む多くの方法は、最終

であるが、他の方法は、デフォルトの実装を有するが、これらによって呼び出されるメソッドdoInBackground()は、抽象およびサブクラスによって定義されることを意図するものであるが、最終ではないが上書きされ許可されます。

関連する問題