GrabDuck

Cybern.ru » Java. Урок 29. Интерфейсы

:

Интерфейс представляет из себя класс, в котором все поля static и final, а все методы абстрактные.
Для того чтобы описать интерфейс, используется ключевое слово interface вместо class:

public interface MyArray {
int Get(int i);
int Set(int i);
int Size();
final int size = 0;
}

Все члены интерфейса по умолчанию являются public static, поэтому явно указывать это не обязательно. Константы интерфейса должны быть обязательно инициализированы, иначе вы не сможете создать его.
Для чего, собственно говоря, нужен интерфейс? Interface используют тогда, когда у нас есть несколько реализаций. То есть, допустим, у нас есть интерфейс MyArray, который содержит три метода. И есть два класса Array и LinkedList. Оба этих класса имеют такой же набор методов, что и интерфейс, но внутри они различаются, например Array умеет быстро отдавать элемент, но иногда медленно добавлять, а LinkedList умеет быстро отдавать, но медленно возвращает элемент по индексу. Тогда в программе вы можете использовать интерфейс и при необходимости сменить плохую реализацию на более подходящую для данного случая, сменив лишь одну строчку, а не заменяя тип данных во всем коде. Итак, перейдем к практическому примеру:
Изменим чуть — чуть наш интерфейс, для удобства реализации:

public interface MyArray {
int Get(int i);//возвращает элемент по индексу
int Add(int value);//кладет элемент в конец массива возвращает его индекс
int Size();//возвращает размер массива
}

Для того, чтобы реализовать интерфейс используется ключевое слово implements:

public class Array implements MyArray {
}

Ключевое слово implements очень похоже на extends, которое мы рассматривали на предыдущих уроках, но применяется только для интерфейсов.
Как вы могли заметить, после того, как вы указали какой интерфейс вы хотите реализовать, среда выдает вам ошибку, и предлагает реализовать три метода, которые написаны в интерфейсе:

public class Array implements MyArray {

@Override
public int Get(int i) {
return 0; //To change body of implemented methods use File | Settings | File Templates.
}

@Override
public int Add(int value) {
return 0; //To change body of implemented methods use File | Settings | File Templates.
}

@Override
public int Size() {
return 0; //To change body of implemented methods use File | Settings | File Templates.
}
}

Хочу заметить, что перед каждой реализацией метода стоит ключевое слово @Override, не забывайте использовать его, если будет программировать вне среды Intellij IDEA.
Например класс Array основан на обычном массиве и может иметь такую реализацию:

public class Array implements MyArray {
int[] array = new int[100];
int size = 0;//количество использованных элементов
@Override
public int Get(int i) {
return array[i];
}

@Override
public int Add(int value) {
array[size] = value;
size++;
if(size==array.length){//если массив закончился
int[] temparray = new int[size * 2];
for(int i = 0; i < size;i++){ temparray[i] = array[i]; } array = temparray; } return size-1; } @Override public int Size() { return size; } }

Такая реализация позволяет быстро обращаться по индексу с помощью метода Get, но страдает некоторыми проблемами при увеличения массива.
Теперь напишем реализацию LinkedList, как я отмечал выше не забывайте пользоваться подсказками среды:

public class LinkedList implements MyArray {
private class Node {
public int value;
public Node next;
}

int size = 0;
Node firstNode = new Node();
Node lastNode = firstNode;

@Override
public int Get(int i) {
Node tempNode = firstNode;
for (int j = 0; j < i; j++) { tempNode = tempNode.next; } return tempNode.value; } @Override public int Add(int value) { lastNode.value = value; lastNode.next = new Node(); lastNode = lastNode.next; size++; return size - 1; } @Override public int Size() { return size; } }

Теперь вместо конкретных классов, мы в программе будем указывать лишь интерфейсы и с легкостью менять реализации:

MyArray superArray = new Array();
superArray = new LinkedList();

Так как во всех функциях и прочих объявлениях у нас написан интерфейс, а не Array или LinkedList, то смена одной реализации на другую будет проходить только в месте объявления, что бывает очень удобно.
Таким образом программист с помощью interface может описать, что класс должен делать, но не писать конкретной реализации, то есть не говоря как.