Java интерфейси

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. Правила за създаване на интерфейси

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

  • константи променливи
  • абстрактни методи
  • статични методи
  • методи по подразбиране

Също така трябва да помним, че:

  • не можем директно да създадем екземпляри за интерфейси
  • интерфейсът може да е празен, без методи или променливи в него
  • не можем да използваме последната дума в дефиницията на интерфейса, тъй като това ще доведе до грешка в компилатора
  • всички декларации на интерфейса трябва да имат публичен или модификатор за достъп по подразбиране; на абстрактен модификатор ще бъде добавен автоматично от компилатора
  • методът на интерфейса не може да бъде частен , защитен или окончателен
  • интерфейсните променливи са публични , статични и окончателни по дефиниция; не ни е позволено да променяме видимостта им

3. Какво можем да постигнем, като ги използваме?

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

Използваме интерфейси за добавяне на определена поведенческа функционалност, която може да се използва от несвързани класове. Например, Comparable , Comparator и Cloneable са Java интерфейси, които могат да бъдат внедрени от несвързани класове. По-долу е даден пример за интерфейса за сравнениекойто се използва за сравняване на два екземпляра от класа Employee :

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 { 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. Полиморфизъм

Нека започнем с задаването на въпроса: какво е полиморфизъм? Това е способността на обекта да приема различни форми по време на изпълнение. За да бъдем по-конкретни, това е изпълнението на метода override, който е свързан със специфичен тип обект по време на изпълнение.

В Java можем да постигнем полиморфизъм, използвайки интерфейси. Например интерфейсът Shape може да приема различни форми - може да бъде кръг или квадрат.

Нека започнем с дефиниране на интерфейса Shape :

public interface Shape { String name(); } 

Сега нека създадем и клас Circle :

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

А също и клас Square :

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. Интерфейс, разширяващ друг интерфейс

Когато интерфейсът разширява друг интерфейс, той наследява всички абстрактни методи на този интерфейс. Нека започнем със създаването на два интерфейса, HasColor и Shape :

public interface HasColor { String getColor(); } public interface Box extends HasColor { int getHeight() } 

В горния пример Box наследява от HasColor с помощта на ключовата дума extends. По този начин интерфейсът на Box наследява getColor . В резултат на това интерфейсът на Box вече има два метода: getColor и getHeight .

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

Когато абстрактният клас реализира интерфейс, той наследява всички свои абстрактни и стандартни методи. Нека разгледаме интерфейса Transform и абстрактния клас Vehicle, който го прилага:

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

В този пример класът Vehicle наследява два метода: абстрактния метод на преобразуване и метода по подразбиране printSpecs .

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

Java има много функционални интерфейси от ранните си дни, като сравним (от Java 1.2) и изпълним (от Java 1.0).

Java 8 представи нови функционални интерфейси като предикат , потребител и функция . За да научите повече за тях, моля, посетете нашия урок за функционални интерфейси в Java 8.

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

В този урок дадохме преглед на Java интерфейсите и говорихме за това как да ги използваме за постигане на полиморфизъм и множество наследства.

Както винаги, пълните примерни кодове са достъпни в GitHub.