Javaの修飾子であるstaticとfinalについて、まずは見ていきます。
staticはフィールドとメソッドに指定し、指定されたフィールドとメソッドは静的フィールドと静的メソッドになります。静的フィールドと静的メソッドはインスタンスを生成しなくても使うことができます。
finalはクラス、フィールド、メソッドに指定します。finalが指定されると変更ができなくなります。
static、finalの用途を整理したものです。
次にabstractです。
abstractは抽象メソッドの宣言に指定します。抽象メソッドとは具体的な処理を書かずプロトタイプ(戻り値と引数)のみを定義したメソッドのことです。抽象メソッドが1つでもあるクラスを抽象クラスと呼びます。抽象クラスのインスタンスは生成することができません。
abstractの用途を整理したものです。
抽象メソッドを持つクラスにはabstract指定が必要です。無いとコンパイルエラーになります。抽象メソッドがない場合でもクラスにabstract指定は可能です。あえて継承して使ってもらいたい場合はクラス修飾子にabstractをつけます。
最後にインターフェイスについてです。
インターフェイスは定数フィールドと抽象メソッドのみで構成されたクラスです(Java8からはデフォルトメソッドとスタティックメソッドが追加されましたがこれについては後述します)。インターフェイスには次のような特徴があります。
- インターフェイスのすべてのフィールドは public static final が指定されているとみなされる。
- インターフェイスのすべてのメソッドは public abstract が指定されているとみなされる。
そのため以下のインターフェイスはまったく同じものです。
インターフェイスのフィールドとメソッドはpublicであるため、インターフェイスのアクセス制限はインターフェイス自身につけられたアクセス修飾子によって決まります。
public interface Keisan1 { ・・ } とした場合、interface句の前にあるpublicがインターフェイス自身につけられたアクセス修飾子となります。
ここからはJava8から追加されたインターフェイスの機能についてです。
インターフェイスの抽象メソッドでは処理の記載はしないのですが、デフォルト処理の記載ができるようになりました。このデフォルト処理を記載したメソッドをデフォルトメソットと呼びます。デフォルト処理というのは、インターフェイスを実装したクラスがインターフェイスに記載されたデフォルト処理をそのまま使う場合に限り、メソッドのオーバーライドが不要となるものです。デフォルトメソッドの宣言には、default修飾子をつけます。
デフォルトメソッドは実装するクラス側のコーディング量を減らすために導入されたものです。実装する側のクラスで、どのクラスも同じ処理となる場合に有効です。
またJava8からはインターフェイスでも静的メソッドが使えるようになりました。クラスと同じようにstatic句をつけることで静的メソッドになります。インターフェイス名.メソッド名 で他のクラスから静的メソッドを呼べます。
インターフェイスのデフォルトメソッドと静的メソッドを使用した例を示します。
Helloインターフェイスではデフォルトメソッドと静的メソッドを宣言します。HelloEnクラスではHelloインターフェイスを実装しますが、デフォルトメソッドをそのまま使います(オーバーライドしません)。HelloJpクラスではHelloインターフェイスを実装して、処理を記載します(オーバーライドします)。MainSampleクラスで、デフォルトメソッド(HelloEnインスタンスのメソッド)、オーバーライドしたメソッド(HelloJpインスタンスのメソッド)、Helloインターフェイスの静的メソッドの呼び出しを行います。
ソースコードは以下です。
Hello.java
public interface Hello {
//デフォルトメソッド
default void hello() {
System.out.println("Hello.");
}
//静的メソッド
static void goodBye() {
System.out.println("Good bye.");
}
}
HelloEn.java
public class HelloEn implements Hello {
//何もしない
}
HelloJp.java
public class HelloJp implements Hello {
//オーバーライドする
public void hello() {
System.out.println("こんにちは");
}
}
MainSample.java
public class MainSample {
public static void main( String[] args ) {
Hello h1 = new HelloEn();
Hello h2 = new HelloJp();
//デフォルトメソッドを呼ぶ
h1.hello();
//オーバーライド下メソッドを呼ぶ
h2.hello();
//静的メソッドを呼ぶ
Hello.goodBye();
}
}
実行結果は以下のようになります。
$ java MainSample
Hello.
こんにちは
Good bye.
なお、default修飾子とstatic修飾子を合わせての指定(static default void hello(). . .)はできませんでした。コンパイルエラー「修飾子staticとdefaultの組合せは不正です」になります。