ご存知のとおり、Java のすべてはオブジェクトで構成されており、オブジェクトには状態 (フィールド) と動作 (メソッドで定義) があります。クラスの動作は、クラスを他のクラスにバインドできるものです。行動にはさまざまな特徴がある場合があり、特に外の世界とやり取りする場合には、行動をクラスの外に移動した方が便利な場合があります。テレビのリモコンが「箱」自体の外側にあるのと同じです。リモコンは、ユーザーが TV 機能と対話するためのインターフェイスです。たとえば、抽象的な飛行機やヘリコプターを実装するクラスを想像できます。ほとんどの鳥など、両方のクラスのオブジェクトは飛行できますが、その動作方法はすべて異なります。おそらく、この機能を別のエンティティに移動し、潜在的なすべての「フライヤー」がこのエンティティから継承されることは価値があるでしょうか? すでに抽象クラスに精通している場合は、抽象クラス Flyable を作成し、そこから Copter クラスと Plane クラスを「継承」することができます。しかし、そのようなプロパティが複数ある場合はどうなるでしょうか? たとえば、飛行機やヘリコプターは飛行することができますが、地上を移動することもできます。Ride クラスを作成しても、Copter と Plane を割り当てることはできなくなります。結局のところ、各 Java クラスには親クラスが 1 つだけあります。Java 言語のインターフェースを使用すると、この問題は部分的に解決されます。Java のインターフェイスは、特定の実装を持たないいくつかの機能を定義し、これらのインターフェイスを使用するクラスによって実装されます。また、1 つのクラスで多数のインターフェイスを実装できます。実際、Java でインターフェイスを実装することにより、クラスが何かを実行できることを宣言し、その動作を報告します。クラス内の動作の具体的な実装はすでに実行されています。それで。飛行機とヘリコプターの離陸方法は異なります。飛行機には滑走路が必要ですが、ヘリコプターは通常垂直に離陸します。このような詳細はクラス内で実装するのが最適です。
Java のインターフェース
Java 言語でインターフェイスを定義するには、interface キーワードを使用します。例えば:interface Voice {
void talk();
}
上記のインターフェイスはVoiceと呼ばれます。Java のインターフェイスでは定数とメソッドを定義できますが、これらには実装がある場合とない場合があります。通常、この例のように、インターフェイス メソッドには実装がありません。実装のないインターフェイス内のメソッドは、抽象クラスの抽象メソッドに似ています。通常、インターフェイス メソッドにはアクセス修飾子がありません。ただし、インターフェイスの目的はクラス実装の機能を定義することであるため、アクセスは実際にはデフォルトでパブリックになります。したがって、すべての機能を実装できるようにオープンにする必要があります。インターフェイスを実装するには、クラスを宣言するときにImplementsキーワードを使用します。さらに、インターフェイスに実装のないメソッドが含まれている場合、そのメソッドは実装クラスで実装する必要があります。
public class Duck implements Voice {
@Override
public void voice() {
System.out.println("Quack");
}
}
インターフェイスコードの例
より完全な例を見てみましょう。すべての(ほとんどすべての)動物は音を出す能力を持っています。この場合、Java インターフェースVoiceを作成しましょう。実装されていないtalk()メソッドがあります。public interface Voice {
void talk();
}
現在、Voiceインターフェースをサポートするすべてのクラスにはtalk()メソッドの実装が必要です。CatとDogという 2 つのクラスを作成し、それらがVoiceインターフェイスを実装していることを示しましょう。この場合、クラスを実装しないとプログラムは動作しません。メソッドの実装は非常に簡単です。Catクラスのオブジェクトのtalk()メソッドを呼び出すと、ニャーと同等のテキストが画面に表示されます。Dogクラスの場合は鳴き声が表示されます。また、ゲッター、セッター、コンストラクターをクラスに追加します。
public class Cat implements Voice {
String name;
String breed;
int year;
public Cat(String name, String breed, int year) {
this.name = name;
this.breed = breed;
this.year = year;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBreed() {
return breed;
}
public void setBreed(String breed) {
this.breed = breed;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
@Override
public void talk() {
System.out.println("meow...");
}
}
public class Dog implements Voice {
String name;
String color;
int year;
public Dog(String name, String color, int year) {
this.name = name;
this.color = color;
this.year = year;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
@Override
public void talk() {
System.out.println("WOF WOF");
}
}
実際、クラスとメソッドの実装は非常に似ています。Voiceサポートを備えた別のクラスParrotを作成しましょう。この中ではtalk()メソッドのみが動作が異なります。ユーザーはコンソールに文字列を入力し、オウムは talk ()メソッドを使用してそれを「繰り返し」ます。
import java.util.Scanner;
public class Parrot implements Voice {
String name;
String color;
int year;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
@Override
public void talk() {
Scanner scanner = new Scanner(System.in);
System.out.println("WHat should I repeat after you?...");
String s = scanner.nextLine();
System.out.println(s);
}
}
次に、テスト クラスを作成し、Cat、Dog 、およびParrotクラスのオブジェクトのtalk()メソッドを順番に呼び出した場合にプログラムがどのような結果を生成するかを見てみましょう。
public class InterfaceDemo {
public static void main(String[] args) {
Cat cat = new Cat ("Mewie", "Siam" ,2021);
cat.talk();
Dog dog = new Dog("Snoopy", "White and black", 2020);
dog.talk();
Parrot parrot = new Parrot();
parrot.talk();
}
}
出力は以下の通りです。緑色のテキストはコンソールに表示される 1 人のユーザーです。
ニャー... ウォフ ウォフ あなたの後に何を繰り返せばいいですか?... 私はとてもおしゃべりで賢い鳥です 私はとてもおしゃべりで賢い鳥です
デフォルトのメソッド
JDK 8 リリースより前は、Java でインターフェイスを実装する場合、そのすべてのメソッドをクラスに実装する必要がありました。同時に、Java インターフェース自体には、特定の実装を持たないメソッド定義のみを含めることができます。JDK 8 では、新しい機能 (デフォルトのメソッド) が追加されています。Java インターフェースにはメソッド定義だけでなくデフォルトの実装も含めることができるようになりました。これらは、クラスがインターフェイスを実装しているがメソッドを実装していない場合に使用されます。たとえば、Voiceインターフェイスのtalk()メソッドをデフォルトのメソッドに変更してみましょう。また、 talkメソッドの実装を持たない新しいVoice対応Duckクラスも作成します。public interface Voice {
default void talk() {
System.out.println("I can talk...");
}
}
public class Duck implements Voice {
public void moveForward() {
System.out.println(" Quack, I am moving forward...");
}
public void TurnRight(){
System.out.println("I am turning right...");
}
public void TurnLeft(){
System.out.println("I am turning left...");
}
public void Stop() {
System.out.println("Quack. I am relaxing on the surface of the water...");
}
public void fly(){
System.out.println("I am flying!!!");
}
}
次に、テストクラスを少し変更してみましょう。
public class InterfaceDemo {
public static void main(String[] args) {
Cat cat = new Cat ("Mewie", "Siam" ,2021);
cat.talk();
Dog dog = new Dog("Snoopy", "White and black", 2020);
dog.talk();
Duck duck = new Duck();
duck.talk();
}
}
出力は次のとおりです。
ニャー…ウォフウォフ、話せるよ…
見る?DogクラスとCatクラスのオブジェクトでは、オーバーライドされたメソッドtalk() が呼び出されますが、Duckクラスのオブジェクトでは、インターフェイスのデフォルト メソッドが呼び出されます。したがって、デフォルトのメソッドは修飾子のない単なるメソッドであり、default キーワードがマークされています。インターフェイスを実装するクラスにデフォルト メソッドを実装する必要はありませんが、オーバーライドできます。
静的メソッド
JDK 8 の静的メソッドは Java インターフェイスで使用できるため、クラス メソッドに似ています。interface Voice {
void talk();
static void check(){
System.out.println("checked...");
}
}
インターフェイスの静的メソッドを参照するには、クラスの場合と同様に、インターフェイスとメソッドの名前を記述します。
public static void main(String[] args) {
Voice.check();
}
インターフェースの複数の実装
Java クラスに複数のインターフェースを適用する必要がある場合、それらはすべて、 implements という単語の後にカンマを付けてリストされます。public class Duck implements Swimmable, Flyable, Voice {
public void moveForward() {
System.out.println(" Quack, I am moving forward...");
}
public void TurnRight(){
System.out.println("I am turning right...");
}
public void TurnLeft(){
System.out.println("I am turning left...");
}
public void Stop() {
System.out.println("Quack. I am relaxing on the surface of the water...");
}
public void fly(){
System.out.println("I am flying!!!");
}
}