Рубрики
Без рубрики

Интерфейсы Java

Изучите концепцию интерфейсов Java и узнайте, как Java использует их для реализации полиморфизма и множественного наследования.

Автор оригинала: Khalid Andari.

1. Обзор

В этом уроке мы поговорим об интерфейсах на Java. Мы также увидим, как Java использует их для реализации полиморфизма и множественного наследования.

2. Что такое интерфейсы в Java?

В Java интерфейс-это абстрактный тип, содержащий набор методов и постоянных переменных. Это одна из основных концепций в Java и используется для достижения абстракции, полиморфизма и множественного наследования .

Давайте рассмотрим простой пример интерфейса на Java:

public interface Electronic {

    // Constant variable
    String LED = "LED";

    // Abstract method
    int getElectricityUse();

    // Static method
    static boolean isEnergyEfficient(String electtronicType) {
        if (electtronicType.equals(LED)) {
            return true;
        }
        return false;
    }

    //Default method
    default void printDescription() {
        System.out.println("Electronic Description");
    }
}

Мы можем реализовать интерфейс в классе Java с помощью ключевого слова implements .

Далее, давайте также создадим Компьютерный класс, реализующий Электронный интерфейс, который мы только что создали:

public class Computer implements Electronic {

    @Override
    public int getElectricityUse() {
        return 1000;
    }
}

2.1. Правила создания интерфейсов

В интерфейсе нам разрешено использовать:

  • константы переменные
  • абстрактные методы
  • статические методы
  • методы по умолчанию

Мы также должны помнить, что:

  • мы не можем создавать экземпляры интерфейсов напрямую
  • интерфейс может быть пустым, в нем нет методов или переменных
  • мы не можем использовать слово final в определении интерфейса, так как это приведет к ошибке компилятора
  • все объявления интерфейса должны иметь модификатор доступа public или по умолчанию; модификатор abstract будет добавлен компилятором автоматически
  • метод интерфейса не может быть закрытым , защищенным или окончательным
  • переменные интерфейса являются общедоступными , статическими и окончательными по определению; нам не разрешается изменять их видимость

3. Чего Мы Можем Достичь, используя Их?

3.1. Поведенческая функциональность

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

public class Employee {

    private double salary;

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
}

public class EmployeeSalaryComparator implements Comparator {

    @Override
    public int compare(Employee employeeA, Employee employeeB) {
        if (employeeA.getSalary() < employeeB.getSalary()) {
            return -1;
        } else if (employeeA.getSalary() > employeeB.getSalary()) { 
            return 1;
        } else {
            return 0;
        }
    }
}

Для получения дополнительной информации, пожалуйста, посетите наш учебник по Comparator и Comparable на Java.

3.2. Множественное Наследование

Классы Java поддерживают сингулярное наследование. Однако, используя интерфейсы, мы также можем реализовать несколько наследований.

Например, в приведенном ниже примере мы замечаем, что Car класс реализует интерфейсы Fly и Transform . Поступая таким образом, он наследует методы fly и transform :

public interface Transform {
    void transform();
}

public interface Fly {
    void fly();
}

public class Car implements Fly, Transform {

    @Override
    public void fly() {
        System.out.println("I can Fly!!");
    }

    @Override
    public void transform() {
        System.out.println("I can Transform!!");
    }
}

3.3. Полиморфизм

Давайте начнем с вопроса: что такое полиморфизм ? Это способность объекта принимать различные формы во время выполнения. Чтобы быть более конкретным, это выполнение метода переопределения, связанного с определенным типом объекта во время выполнения.

В Java мы можем достичь полиморфизма с помощью интерфейсов. Например, интерфейс Shape может принимать различные формы — это может быть Круг или Квадрат.

Давайте начнем с определения Формы интерфейса:

public interface Shape {
    String name();
}

Теперь давайте также создадим класс Circle :

public class Circle implements Shape {

    @Override
    public String name() {
        return "Circle";
    }
}

А также Квадрат класс:

public class Square implements Shape {

    @Override
    public String name() {
        return "Square";
    }
}

Наконец, пришло время увидеть полиморфизм в действии, используя наш интерфейс Shape и его реализации. Давайте создадим экземпляры некоторых объектов Shape , добавим их в Список , и, наконец, напечатаем их имена в цикле:

List shapes = new ArrayList<>();
Shape circleShape = new Circle();
Shape squareShape = new Square();

shapes.add(circleShape);
shapes.add(squareShape);

for (Shape shape : shapes) {
    System.out.println(shape.name());
}

4. Методы по умолчанию в интерфейсах

Традиционные интерфейсы в Java 7 и ниже не обеспечивают обратную совместимость.

Это означает, что если у вас есть устаревший код, написанный на Java 7 или более ранней версии, и вы решили добавить абстрактный метод в существующий интерфейс, то все классы, реализующие этот интерфейс, должны переопределить новый абстрактный метод . В противном случае код будет нарушен.

Java 8 решила эту проблему, введя метод по умолчанию , который является необязательным и может быть реализован на уровне интерфейса.

5. Правила Наследования интерфейса

Чтобы добиться множественного наследования через интерфейсы, мы должны помнить несколько правил. Давайте рассмотрим это подробно.

5.1. Интерфейс, Расширяющий Другой Интерфейс

Когда интерфейс расширяет другой интерфейс, он наследует все абстрактные методы этого интерфейса. Давайте начнем с создания двух интерфейсов, Имеющих цвет и Форму :

public interface HasColor {
    String getColor();
}

public interface Box extends HasColor {
    int getHeight()
}

В приведенном выше примере Поле наследуется от Имеет цвет с использованием ключевого слова расширяется. Таким образом, интерфейс Box наследует getColor . В результате интерфейс Box теперь имеет два метода: getColor и getHeight .

5.2. Абстрактный класс, реализующий интерфейс

Когда абстрактный класс реализует интерфейс, он наследует все свои абстрактные методы и методы по умолчанию. Давайте рассмотрим интерфейс Transform и абстрактный класс Транспортное средство , который его реализует:

public interface Transform {
    
    void transform();
    default void printSpecs(){
        System.out.println("Transform Specification");
    }
}

public abstract class Vehicle implements Transform {}

В этом примере класс Vehicle наследует два метода: метод abstract transform и метод по умолчанию Спецификации печати .

6. Функциональные Интерфейсы

Java с самого начала имела множество функциональных интерфейсов, таких как Сопоставимый (начиная с Java 1.2) и Управляемый (начиная с Java 1.0).

Java 8 представила новые функциональные интерфейсы, такие как Предикат , Потребитель и Функция . Чтобы узнать больше об этом, пожалуйста, посетите наш учебник по Функциональным интерфейсам в Java 8 .

7. Заключение

В этом уроке мы дали обзор интерфейсов Java и рассказали о том, как их использовать для достижения полиморфизма и множественного наследования.

Как всегда, полные образцы кода доступны на GitHub.