0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Java Silver確実合格を目指すカレンダーAdvent Calendar 2024

Day 9

【Java】インタフェースについて

Last updated at Posted at 2024-12-08

インタフェースとは

公開すべき必要な操作をまとめたクラスの仕様のこと。以下にインタフェースの特長をまとめる。

インスタンス化できない

Java(Main.java)
public class Main implements Foo {
	public static void main(String[] args) {
		Foo foo = new Foo();
	}
}

interface Foo{
	int num1 = 10;
	final int num2 = 20;
}

結果

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	型 Foo のインスタンスを生成できません

	at Main.main(Main.java:3)

インタフェースの多重実現が可能

Java(Main.java)
public class Main implements Foo,Foo2 {
	public static void main(String[] args) {
		System.out.println(Foo.num1);
		System.out.println(Foo2.num1);
	}
}

interface Foo{
	int num1 = 10;
	final int num2 = 20;
}

interface Foo2{
	int num1 = 20;
	final int num2 = 30;
}

結果

10
20

インタフェースの多重継承も可能

Java(Main.java)
public class Main implements Foo,Foo2 {
	public static void main(String[] args) {
		System.out.println(Foo.num1);
		System.out.println(Foo2.num1);
		System.out.println(Foo3.num3);
	}
}

interface Foo{
	int num1 = 10;
	final int num2 = 20;
}

interface Foo2{
	int num1 = 20;
	final int num2 = 30;
}

interface Foo3 extends Foo,Foo2{
	int num3 = 50;
}

結果

10
20
50

ただし以下の呼び方をするとエラーになる。

Java(Main.java)
public class Main implements Foo,Foo2 {
	public static void main(String[] args) {
		System.out.println(Foo.num1);
		System.out.println(Foo2.num1);
		System.out.println(Foo3.num1);//エラー
	}
}

interface Foo{
	int num1 = 10;
	final int num2 = 20;
}

interface Foo2{
	int num1 = 20;
	final int num2 = 30;
}

interface Foo3 extends Foo,Foo2{
	int num3 = 50;
}

結果

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	フィールド Foo3.num1 はあいまいです

	at Main.main(Main.java:5)

インタフェースで定義した変数は自動的にpublic static finalになる

Java(Main.java)
public class Main implements Foo{
	public static void main(String[] args) {
		Foo.num1 = 20;
	}
}

interface Foo{
	int num1 = 10;
	final int num2 = 20;
}

結果

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	final フィールド Foo.num1 には代入できません

	at Main.main(Main.java:3)

インタフェースで定義する変数(インスタンス変数・static変数)のアクセス修飾子はpublicのみ

デフォルトの場合は自動的にpublicに読み替えられる。protectedとprivateはエラー。

Java(Main.java)
interface Foo{
	public int num1 = 10;
	protected int num2 = 20;//エラー
	int num3 = 30;
	private num4 = 40;//エラー
}

インタフェースで定義するデフォルトメソッドのアクセス修飾子はpublicのみ

デフォルトの場合は自動的にpublicに読み替えられる。protectedとprivateはエラー。

Java(Main.java)
	default public int number1(){
		return 10;
	}
	default protected int number2(){//エラー
		return 20;
	}
	default int number3(){
		return 40;
	}
	default private int number4(){//エラー
		return 40;
	}

インタフェースで定義するstaticメソッドのアクセス修飾子はpublicとprivateのみ

デフォルトの場合は自動的にpublicに読み替えられる。protectedはエラー。

Java(Main.java)
	public static int number1() {
		return 10;
	}
	protected static int number2() {//エラー
		return 20;
	}
	static int number3() {
		return 30;
	}
	private static int number4() {
		return 40;
	}

インタフェースに定めたメソッドは実現しないといけない

Java(Main.java)
 public class Main {
	public static void main(String[] args) {
		Add add = new Add();
		System.out.println(add.calc(2,7));
	}
}

interface Foo{
	public int calc(int a,int b);
}

//Fooの継承
//Calcメソッド実装
class Add implements Foo{
	public int calc(int a,int b) {
		return a + b;
	}
}

結果

9

デフォルトメソッドでjava.lang.Objectのメソッドをオーバーライドできない

Java(Main.java)
interface Foo{
	default String toString() { //エラー
		return "aaa";
	}
}

元のデフォルトメソッドを呼び出す場合、インタフェース名.super.メソッド名で呼び出す

Java(Main.java)
public class Main {
	public static void main(String[] args) {
		Add add = new Add();
		System.out.println(add.calc(2,7));
		System.out.println(add.callSuperNum(2,7));
	}
}

interface Foo{
	default int num(int a,int b) { 
		return a * b;
	}
}

//Fooの継承
//Calcメソッド実装
class Add implements Foo{
	public int calc(int a,int b) {
		return a + b;
	}
	public int callSuperNum(int a,int b) {
		return Foo.super.num(a, b);
	}
}

結果

9
14

共変戻り値について

これはインタフェースを実装したメソッド、またはサブクラスでオーバーライドするメソッドの戻り値が、その戻り値のサブクラスでも良いという仕様。

Java(A.java)
public interface A{
	public Iterable a();
}
Java(B.java)
import java.util.Collection;

public interface B extends A{
	public Collection a();
}
Java(C.java)
import java.nio.file.Path;

public interface C extends A{
	public Path a();
}

BインタフェースとCインタフェースでaメソッドを実装しているが、AインタフェースのIterable型で戻していない。IterableインタフェースはCollectionやPathのスーパーインタフェースなので、問題無く動く。

まとめ

  • インスタンス化できない
  • インタフェースの多重実現が可能
  • インタフェースの多重継承も可能
  • インタフェースで定義した変数は自動的にpublic static finalになる
  • インタフェースで定義する変数(インスタンス変数・static変数)のアクセス修飾子はpublicのみ
  • インタフェースで定義するデフォルトメソッドのアクセス修飾子はpublicのみ
  • インタフェースで定義するstaticメソッドのアクセス修飾子はpublicとprivateのみ
  • インタフェースに定めたメソッドは実現しないといけない
  • デフォルトメソッドでjava.lang.Objectのメソッドをオーバーライドできない
  • 元のデフォルトメソッドを呼び出す場合、インタフェース名.super.メソッド名で呼び出す
  • 共変戻り値とはインタフェースを実装したメソッド、またはサブクラスでオーバーライドするメソッドの戻り値が、その戻り値のサブクラスでも良いという仕様
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?