Интерфейс в Java является одним из основных концепций. Java Interface – это основная часть языка программирования Java и используется не только в JDK, но и в шаблонах проектирования Java. Большинство фреймворков активно используют интерфейсы Java.
Интерфейс в Java
Интерфейс в Java предоставляет способ достижения абстракции. Java interface также используется для определения контракта, который должны реализовать подклассы. Например, допустим, мы хотим создать рисунок, состоящий из нескольких фигур. Здесь мы можем создать интерфейс
Shape
и определить все методы, которые будут реализованы различными типами объектов Shape. Для упрощения мы можем оставить только два метода – draw()
для отрисовки фигуры и getArea()
, который будет возвращать площадь фигуры.
Пример интерфейса Java
Исходя из вышеприведенных требований, наш интерфейс Shape будет выглядеть следующим образом. Shape.java
package com.journaldev.design;
public interface Shape {
//неявно public, static и final
public String LABLE="Shape";
//методы интерфейса неявно абстрактные и public
void draw();
double getArea();
}
Важные моменты об интерфейсе в Java
-
interface
– это код, который используется для создания интерфейса в Java. -
Мы не можем создать экземпляр интерфейса в Java.
-
Интерфейс предоставляет абсолютную абстракцию. В предыдущем посте мы узнали о абстрактных классах в Java, чтобы предоставить абстракцию, но абстрактные классы могут иметь реализацию методов, а интерфейсы – нет.
-
Интерфейсы не могут иметь конструкторы, потому что мы не можем создавать их экземпляры, и интерфейсы не могут иметь метода с телом.
-
По умолчанию любой атрибут интерфейса является public, static и final, поэтому нам не нужно предоставлять модификаторы доступа к атрибутам, но если мы это делаем, компилятор также не жалуется.
-
По умолчанию методы интерфейса неявно являются abstract и public, что вполне логично, потому что у метода нет тела, и подклассы могут предоставить реализацию метода.
-
Интерфейс не может расширять класс, но может расширять другой интерфейс. Примером является
public interface Shape extends Cloneable{}
, где интерфейс расширяет другой интерфейс. Фактически в Java предоставляется множественное наследование в интерфейсах, что означает, что интерфейс может расширять несколько интерфейсов. -
implements
ключ используется классами для реализации интерфейса. -
Класс, реализующий интерфейс, должен предоставить реализацию всех его методов, если это не абстрактный класс. Например, мы можем реализовать вышеуказанный интерфейс в абстрактном классе, как показано ниже:
ShapeAbs.java
package com.journaldev.design; public abstract class ShapeAbs implements Shape { @Override public double getArea() { // TODO Автоматически созданный метод-заглушка return 0; } }
-
Всегда старайтесь писать программы в терминах интерфейсов, а не реализаций, чтобы заранее знать, что классы реализации всегда будут предоставлять реализацию, и в будущем, если появится более хорошая реализация, мы легко можем перейти к ней.
Пример реализации интерфейса на Java
Теперь давайте рассмотрим некоторые реализации нашего интерфейса Shape на Java. Circle.java
package com.journaldev.design;
public class Circle implements Shape {
private double radius;
public Circle(double r){
this.radius = r;
}
@Override
public void draw() {
System.out.println("Drawing Circle");
}
@Override
public double getArea(){
return Math.PI*this.radius*this.radius;
}
public double getRadius(){
return this.radius;
}
}
Обратите внимание, что класс Circle реализовал все методы, определенные в интерфейсе, и у него также есть некоторые собственные методы, такие как getRadius()
. Реализации интерфейса могут иметь несколько типов конструкторов. Давайте рассмотрим другую реализацию интерфейса для интерфейса Shape. Rectangle.java
package com.journaldev.design;
public class Rectangle implements Shape {
private double width;
private double height;
public Rectangle(double w, double h){
this.width=w;
this.height=h;
}
@Override
public void draw() {
System.out.println("Drawing Rectangle");
}
@Override
public double getArea() {
return this.height*this.width;
}
}
Обратите внимание на использование аннотации @Override, узнайте о аннотациях в Java и почему мы всегда должны использовать аннотацию @Override при переопределении метода в Java. Вот тестовая программа, демонстрирующая, как программировать в терминах интерфейсов, а не реализаций. ShapeTest.java
package com.journaldev.design;
public class ShapeTest {
public static void main(String[] args) {
//программирование для интерфейсов, а не реализаций
Shape shape = new Circle(10);
shape.draw();
System.out.println("Area="+shape.getArea());
//легкость переключения с одной реализации на другую
shape=new Rectangle(10,10);
shape.draw();
System.out.println("Area="+shape.getArea());
}
}
Результат работы приведенной выше программы на примере интерфейса Java:
Drawing Circle
Area=314.1592653589793
Drawing Rectangle
Area=100.0
Преимущества интерфейса Java
- Интерфейс предоставляет контракт для всех классов реализации, поэтому хорошо программировать в терминах интерфейсов, потому что классы реализации не могут удалять используемые нами методы.
- Интерфейсы хороши для определения типа и создания иерархии верхнего уровня в нашем коде.
- Поскольку класс Java может реализовывать несколько интерфейсов, в большинстве случаев лучше использовать интерфейсы в качестве суперкласса.
Недостатки интерфейса Java
Хотя интерфейсы предоставляют множество преимуществ, у них также есть некоторые недостатки.
-
Необходимо очень внимательно выбирать методы интерфейса при проектировании нашего проекта, поскольку мы не можем добавлять или удалять методы из интерфейса в последующем, это приведет к ошибке компиляции для всех классов реализации. Иногда это приводит к тому, что в нашем коде появляется много интерфейсов, расширяющих базовый интерфейс, что делает его сложным для поддержки.
-
Если у реализующих классов есть свои собственные методы, мы не можем использовать их напрямую в нашем коде, потому что тип Object – это интерфейс, у которого нет этих методов. Например, в приведенном выше коде мы получим ошибку компиляции для кода
shape.getRadius()
. Чтобы преодолеть это, мы можем использовать приведение типов и использовать метод следующим образом:Circle c = (Circle) shape; c.getRadius();
Хотя приведение типов класса имеет свои недостатки.
Это все, что у меня есть по интерфейсу в Java. Поскольку мы часто используем интерфейс Java, мы должны знать его возможности. Убедитесь, что вы используете интерфейсы при проектировании системы и в качестве контракта между клиентом и подклассами, реализующими интерфейсы. Обновление: В Java 8 было изменено определение интерфейсов с введением реализации методов по умолчанию и статических методов. Дополнительные сведения можно найти в интерфейсе Java 8.
Source:
https://www.digitalocean.com/community/tutorials/interface-in-java