こんにちは、ともです。
今回は、JavaSE8からの機能である、インタフェース内で実装できるようになった、staticメソッドとdefaultメソッドについて私の理解をまとめておきます。
staticメソッドとは
インタフェースの中では、抽象メソッドしか記述しなかったが。
staticにより、インタフェース固有の実装したメソッドを書くことができるようになった。
普通のクラスと同様に「インタフェース名.メソッド名」でアクセス可能である。
package Interface;
public class Main {
public interface Test{
static void test() {
System.out.println("test method");
}
}
public static void main(String[] args) {
Test.test();// "test method"が出力
}
}
defaultメソッドとは
defaultと先頭につけたメソッドを記述することにより、インタフェースを実装したクラス全てに共通のメソッドを持たせることが可能となりました。
public class Main {
public interface Test{
default void implementMethodInTest() {
System.out.println("Testインタフェースで実装したメソッド");
}
}
public static void main(String[] args) {
class Hoge implements Test{};
Hoge hoge = new Hoge();
hoge.implementMethodInTest();// Testインタフェースで実装したメソッドと出力
}
}
このように継承先のクラス(Hoge)ではなく、インタフェースにメソッドを実装できます。
コンパイルエラーになる例
defaultである同一シグニチャのメソッドを同時に実装した場合にエラーとなります。
public class Main {
// AとBはmethodという同じシグニチャのdefaultメソッドをもつ
public interface A{
default void method() {
System.out.println("A's method");
}
}
public interface B {
default void method() {
System.out.println("B's method");
}
}
public static void main(String[] args) {
// どっちのdefaultを採用していいかわからない。
class Hoge implements A, B{};
}
}
AとBのインタフェースを実装したが、どちらのdefaultメソッドを採用したら良いのか判定できないためコンパイルエラーとなります。
パラメーター () および () を持つ重複した default メソッド method は型 Main.B および Main.A から継承されています
しかし、次のように距離が異なる場合は可能となります。
public class Main {
// BよりHogeに遠い
public interface X{
default void method() {
System.out.println("A's method");
}
};
public interface A extends X{
}
// XよりもHogeに近い
public interface B extends X {
default void method(){
System.out.println("B's method");
}
}
public static void main(String[] args) {
// どっちのdefaultを採用していいかわからない。
class Hoge implements A, B{};
Hoge hoge = new Hoge();
hoge.method();//B's method
}
}
BインタフェースとXインタフェースで同一シグニチャのdefaultメソッドが実装されています。
この場合、Hogeクラスに近いBインタフェースがHogeクラスで採用されます。
まとめ
staticメソッドとdefaultメソッドについて理解をまとめました。
知っておくと実装の幅が広がりそうですね。JavaGoldの資格でも出る所ですので、抑えておきましょう。