『Effective Java 第2版 (The Java Series)』を読むまで知らなかったのですが、Java SE 5 から Java SE 6 に移行する際に @Override アノテーション*1の使用方法が変更になっていたそうで。
一言で言えば、「インターフェースに宣言されているメソッドをオーバーライドする際にも @Override アノテーションを使える」ように拡張されました。 確かに Java SE 5 の頃に何故こういう風に使えないんだ!と思ったことがありましたが、拙者だけではなかったのですね。
以下で、Java SE 5 と Java SE 6 の間の @Override アノテーションの使い方の違いを、サンプル・コードを用いて見ていきましょう。
分類表
拡張する型 (extends) と拡張される型 (super) で、有り得る組合せは以下の表の通り:
extends \ super | インターフェース | 抽象クラス | 具象クラス |
---|---|---|---|
インターフェース | interface I extends I | - | - |
抽象クラス | abstract class AC implements I |
abstract class AC extends AC |
abstract class AC extends CC |
具象クラス | class CC implements I | class CC extends AC | class CC extends CC |
ここで
- I:インターフェース
- AC:抽象クラス
- CC:具象クラス
です。 Java SE 6 から @Override アノテーションを付加することが可能になったのは、拡張される型 (super) がインターフェースの場合です(黄色い部分)。 それ以外のものは従来から可能です。
インターフェースを拡張する
Java SE 6 で @Override アノテーションを付加できるようになったのは「インターフェースを拡張する」場合です。
インターフェース extends インターフェース
interface SuperInterface{ void method(); } interface Interface extends SuperInterface{ /** Java SE 6 から可能に。 */ @Override void method(); }
抽象クラス implements インターフェース
interface Interface{ void method1(); void method2(); } abstract class AbstractClass implements Interface{ /** Java SE 6 から可能に。 */ @Override public abstract void method1(); /** Java SE 6 から可能に。 */ @Override public void method2(){} }
「抽象メソッドでオーバーライド」する場合と「具象メソッドでオーバーライド」する場合がありますが、どちらも可能になりました。
具象クラス implements インターフェース
interface Interface{ void method(); } class ConcreteClass implements Interface{ /** Java SE 6 から可能に。 */ @Override public void method(){} }
抽象クラスを拡張する
これ以降(具象クラスを拡張する場合も)は、Java SE 5 と Java SE 6 との間に、@Override アノテーションの使用方法に違いはないので、別に読み飛ばしても構いません。
抽象クラス extends 抽象クラス
abstract class SuperAbstractClass{ public abstract void abstractMethod1(); public abstract void abstractMethod2(); public void concreteMethod1(){} public void concreteMethod2(){} } abstract class AbstractClass extends SuperAbstractClass{ /** もともと OK */ @Override public abstract void abstractMethod1(); /** もともと OK */ @Override public void abstractMethod2(){} /** もともと OK */ @Override public abstract void concreteMethod1(); /** もともと OK */ @Override public void concreteMethod2(){} }
オーバライドするメソッド・されるメソッドが抽象メソッドか具象メソッドかで、4パターンあります。
具象クラス extends 抽象クラス
abstract class SuperAbstractClass{ public abstract void abstractMethod(); public void concreteMethod(){} } class ConcreteClass extends SuperAbstractClass{ /** もともと OK */ @Override public void abstractMethod(){} /** もともと OK */ @Override public void concreteMethod(){} }
具象クラスを拡張する
ここも Java SE 5 と Java SE 6 との間で、@Override アノテーションの使用方法に違いはありません。 そもそも、具象クラスを拡張すること自体、あまり推奨されていません。
抽象クラス extends 具象クラス
class SuperConcreteClass{ public void method1(){} public void method2(){} } abstract class AbstractClass extends SuperConcreteClass{ /** もともと OK */ @Override public abstract void method1(); /** もともと OK */ @Override public void method2(){} }
具象クラス extends 具象クラス
class SuperConcreteClass{ public void method(){} } class ConcreteClass extends SuperConcreteClass{ /** もともと OK */ @Override public void method(){} }
Effective Java 第2版 (The Java Series)
- 作者: Joshua Bloch,柴田芳樹
- 出版社/メーカー: ピアソンエデュケーション
- 発売日: 2008/11/27
- メディア: 単行本(ソフトカバー)
- 購入: 77人 クリック: 936回
- この商品を含むブログ (262件) を見る