Шаг 42.
Язык программирования Java.
Свойства интерфейсов

На этом шаге мы рассмотрим cвойства интерфейсов

Интерфейсы - это не классы. В частности, с помощью операции new нельзя создать экземпляр интерфейса следующим способом:

x = new Comparable(...);

Но, несмотря на то, что конструировать интерфейсные объекты нельзя, объявлять интерфейсные переменные можно следующим способом:

Comparable x;

При этом интерфейсная переменная должна ссылаться на объект класса, реализующего данный интерфейс, как в приведенном ниже фрагменте кода:

x = Employee(...); /*Верно, если класс Employee реализует интерфейс Comparable*/

Как известно, в ходе операции instanceof провераяется, принадлежит ли объект заданному классу. Но с помощью этой операции можно также проверить, реализует ли объект заданный интерфейс:

if (anObject instanceof Comparable) {...}

Аналогично классам, интерфейсы также могут образовывать иерархию наследования. Это позволяет создавать цепочки интерфейсов в направлении от более абстрактных к более специализированным. Допустим, имеется следующий интерфейс Moveable:

public interface Moveable {
    void move(double x, double y);
}

В таком случае можно создать интерфейс Powered, расширяющий интерфейс Moveable следующим образом:

public interface Powered extends Moveable {
    double milesPerGallon();
}

И хотя в интерфейсе не может быть ни полей экземпляров, ни статических методов, в нем можно объявлять константы, как показано ниже:

public interface Powered extends Moveable {
    double milesPerGallon();
    double SPEED_LIMIT = 95; /*открытая статическая конечная константа*/
}

Как и методы, поля для констант в интерфейсах автоматически становятся открытыми. А кроме того, они являются статическими и конечными (то есть имеют по умолчанию модификаторы доступа public static final).

В некоторых интерфейсах объявляются только константы и ни одного метода. Например, в стандартной библиотеке содержится интерфейс SwingConstants, определяющий константы NORTH, SOUTH, HORIZONTAL и так далее. Любой класс, реализующий интерфейс SwingConstants, автоматически наследует эти константы. Его методы могут, например, непосредственно ссылаться на константу NORTH, не используя громоздкое обозначение SwingConstants.NORTH. Но многие специалисты считают, что такое использование интерфейсов со временем изживет себя. Мы так же не рекомендуем применять их с этой целью.

В Java любой класс может иметь только один суперкласс, но в то же время любой класс может реализовывать несколько интерфейсов. Это позволяет максимально гибко определять поведение класса. Например, в Java имеется очень важный интерфейс Cloneable. Так, если некоторый класс реализует интерфейс Cloneable, для создания точных копий его объектов можно применять метод clone() из класса Object. Допустим далее, что требуется не только создавать клоны объектов данного класса, но и сравнивать их. Тогда нужно просто реализовать в этом классе оба интерфейса, Cloneable и Comparable, следующим образом:

class Employee implements Cloneable, Comparable {
    ...
}

Для разделения имен интерфейсов, задающих свойства классов, служит запятая.

Возникают следующие вопросы: зачем разработчики языка Java создали механизм интерфейсов и почему бы не сделать интерфейс Comparable абстрактным классом, например, так, как показано ниже?

abstract class Comparable {
    public abstract int compareTo(Object other);
}

В таком случае рассматриваемый здесь класс Employee мог бы просто расширять абстрактный класс и реализовывать метод compareTo() следующим образом:

class Employee extends Comparable {
    public int compareTo(Object other) {...}
}

К сожалению, это породило бы массу проблем, связанных с использованием абстрактного базового класса для выражения обобщенного свойства. Ведь класс может расширять только один класс. Допустим, класс Employee уже является подклассом какого-нибудь другого класса, скажем, Person. Это означает, что он уже не может расширять еще один класс. Но в то же время каждый класс может реализовывать сколько угодно интерфейсов.

На следующем шаге мы поговорим про обратные вызовы

Предыдущий шаг Содержание Следующий шаг