Для создания класса согласованного с некоторым интерфейсом (или группой интерфейсов) используется ключевое слово implements. При этом класс согласованный с интерфейсом является обычным и в последствии может быть унаследован. Методы, объявленные в интерфейсе, при реализации класса должны быть определены как public. В противном случае, они будут по умолчанию friendly и доступ к ним во время наследования запрещен компилятором.
import java.util.*;
interface Instrument {
int i = 5; // static & final
void play(); // автоматически public
String what();
void adjust();
}
class A implements Instrument {
public void play() {
System.out.println("Wind.play()");
}
public String what() { return "Wind"; }
public void adjust() {}
}
class B implements Instrument {
public void play() {
System.out.println("Percussion.play()");
}
public String what() { return "Percussion"; }
public void adjust() {}
}
class AA extends A {
public void play() {
System.out.println("Brass.play()");
}
public void adjust() {
System.out.println("Brass.adjust()");
}
}
class BB extends B {
public void play() {
System.out.println("Woodwind.play()");
}
public String what() { return "Woodwind"; }
}
public class Music {
static void tune(Instrument i) {
// ...
i.play();
}
static void tuneAll(Instrument[] e) {
for(int i = 0; i < e.length; i++)
tune(e[i]);
}
public static void main(String[] args) {
Instrument[] orchestra = new Instrument[4];
int i = 0;
// Приведение к базовому типу во время добавления в массив:
orchestra[i++] = new A();
orchestra[i++] = new B();
orchestra[i++] = new AA();
orchestra[i++] = new BB();
tuneAll(orchestra);
}
} ///:~
Можно создавать ссылки на интерфейсы. Конечно, указывать такая ссылка может только на какую-нибудь реализацию интерфейса. Тем самым мы получаем еще один способ организации полиморфизма. Как видно из примера, можно объявлять переменные как объектные ссылки для инициализации которых используется не тип класса, а интерфейсный тип. Такую переменную можно инициализировать ссылкой на объект любого класса реализующего данный интерфейс. Через такую ссылку можно вызывать верную версию метода (динамически), основываясь на актуальном экземпляре интерфейса. Через переменную интерфейсной ссылки можно обращаться только к методам, объявленным в интерфейсе и реализованным в классе. Ссылку нельзя использовать для обращения к частным методам класса.
Если интерфейс не включает в себя методы, то любой класс, объявляемый реализацией этого интерфейса, может вообще ничего не реализовывать. Для импорта констант в пространство имен класса предпочтительнее использовать переменные с модификатором final. В следующем примере показано использование интерфейса для совместно используемых констант.