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

Изменения интерфейса Java 8 – статический метод, метод по умолчанию

Изменения интерфейса Java 8. Статический метод интерфейса Java, метод интерфейса Java по умолчанию, статические методы интерфейса Java 8 и пример кода методов по умолчанию.

Автор оригинала: Pankaj Kumar.

Изменения интерфейса Java 8 включают статические методы и методы по умолчанию в интерфейсах. До Java 8 у нас могли быть только объявления методов в интерфейсах. Но с Java 8 мы можем использовать методы по умолчанию и статические методы в интерфейсах.

Интерфейс Java 8

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

Давайте рассмотрим методы интерфейса по умолчанию и методы статического интерфейса и причины их введения в изменения интерфейса Java 8.

Метод интерфейса Java По умолчанию

Для создания метода по умолчанию в интерфейсе java нам нужно использовать ключевое слово ” default ” с подписью метода. Например,

package com.journaldev.java8.defaultmethod;

public interface Interface1 {

	void method1(String str);
	
	default void log(String str){
		System.out.println("I1 logging::"+str);
	}
}

Обратите внимание, что log(String str) является методом по умолчанию в интерфейсе 1 . Теперь, когда класс будет реализовывать Интерфейс1, не обязательно предоставлять реализацию методов интерфейса по умолчанию. Эта функция поможет нам расширить интерфейсы с помощью дополнительных методов, все, что нам нужно, – это предоставить реализацию по умолчанию.

Допустим, у нас есть другой интерфейс со следующими методами:

package com.journaldev.java8.defaultmethod;

public interface Interface2 {

	void method2();
	
	default void log(String str){
		System.out.println("I2 logging::"+str);
	}

}

Мы знаем, что Java не позволяет нам расширять несколько классов, потому что это приведет к “Алмазной проблеме”, когда компилятор не сможет решить, какой метод суперкласса использовать. При использовании методов по умолчанию проблема с алмазами возникнет и для интерфейсов. Потому что, если класс реализует как Интерфейс 1 , так и Интерфейс 2 и не реализует общий метод по умолчанию, компилятор не может решить, какой из них выбрать.

Расширение нескольких интерфейсов является неотъемлемой частью Java, вы найдете его в основных классах java, а также в большинстве корпоративных приложений и фреймворков. Поэтому, чтобы убедиться, что эта проблема не возникнет в интерфейсах, необходимо обеспечить реализацию общих методов интерфейсов по умолчанию. Поэтому, если класс реализует оба вышеуказанных интерфейса, он должен будет предоставить реализацию для метода log () , иначе компилятор выдаст ошибку во время компиляции.

Простой класс, реализующий как Интерфейс1 , так и Интерфейс2 , будет:

package com.journaldev.java8.defaultmethod;

public class MyClass implements Interface1, Interface2 {

	@Override
	public void method2() {
	}

	@Override
	public void method1(String str) {
	}

	@Override
	public void log(String str){
		System.out.println("MyClass logging::"+str);
		Interface1.print("abc");
	}
}

Важные моменты о методах интерфейса java по умолчанию:

  1. Методы интерфейса Java по умолчанию помогут нам расширить интерфейсы, не опасаясь нарушения классов реализации.
  2. Методы интерфейса Java по умолчанию устраняют различия между интерфейсами и абстрактными классами.
  3. Методы интерфейса Java 8 по умолчанию помогут нам избежать служебных классов, таких как все методы класса коллекций, которые могут быть предоставлены в самих интерфейсах.
  4. Методы интерфейса Java по умолчанию помогут нам в удалении базовых классов реализации, мы можем предоставить реализацию по умолчанию, и классы реализации могут выбрать, какой из них переопределить.
  5. Одной из основных причин введения методов по умолчанию в интерфейсы является расширение API коллекций в Java 8 для поддержки лямбда-выражений.
  6. Если какой-либо класс в иерархии имеет метод с такой же сигнатурой, то методы по умолчанию становятся неактуальными. Метод по умолчанию не может переопределить метод из java.lang.Объект . Рассуждения очень просты, это потому, что Object является базовым классом для всех классов java. Поэтому, даже если у нас есть методы класса объектов, определенные в интерфейсах как методы по умолчанию, это будет бесполезно, потому что метод класса объектов всегда будет использоваться. Вот почему, чтобы избежать путаницы, у нас не может быть методов по умолчанию, которые переопределяют методы класса объектов.
  7. Методы интерфейса Java по умолчанию также называются методами защиты или методами виртуального расширения.

Статический метод интерфейса Java

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

package com.journaldev.java8.staticmethod;

public interface MyData {

	default void print(String str) {
		if (!isNull(str))
			System.out.println("MyData Print::" + str);
	}

	static boolean isNull(String str) {
		System.out.println("Interface Null Check");

		return str == null ? true : "".equals(str) ? true : false;
	}
}

Теперь давайте рассмотрим класс реализации, имеющий метод isNull() с плохой реализацией.

package com.journaldev.java8.staticmethod;

public class MyDataImpl implements MyData {

	public boolean isNull(String str) {
		System.out.println("Impl Null Check");

		return str == null ? true : false;
	}
	
	public static void main(String args[]){
		MyDataImpl obj = new MyDataImpl();
		obj.print("");
		obj.isNull("abc");
	}
}

Обратите внимание, что равно Null(String str) является простым методом класса, он не переопределяет метод интерфейса. Например, если мы добавим @Переопределение аннотации в метод isNull (), это приведет к ошибке компилятора.

Теперь, когда мы запустим приложение, мы получим следующий вывод.

Interface Null Check
Impl Null Check

Если мы сделаем метод интерфейса статическим по умолчанию, мы получим следующий вывод.

Impl Null Check
MyData Print::
Impl Null Check

Статический метод интерфейса Java виден только для методов интерфейса, если мы удалим метод isNull() из класса Мои данные , мы не сможем использовать его для объекта MyDataImpl . Однако, как и другие статические методы, мы можем использовать статические методы интерфейса, использующие имя класса. Например, допустимым утверждением будет:

boolean result = MyData.isNull("abc");

Важные моменты о статическом методе интерфейса java:

  1. Статический метод интерфейса Java является частью интерфейса, мы не можем использовать его для объектов класса реализации.
  2. Статические методы интерфейса Java хороши для предоставления служебных методов, таких как проверка на нуль, сортировка коллекций и т.д.
  3. Статический метод интерфейса Java помогает нам обеспечить безопасность, не позволяя классам реализации переопределять их.
  4. Мы не можем определить статический метод интерфейса для методов класса объектов, мы получим ошибку компилятора как “Этот статический метод не может скрыть метод экземпляра от объекта”. Это связано с тем, что это запрещено в java, поскольку объект является базовым классом для всех классов, и у нас не может быть статического метода уровня класса и другого метода экземпляра с одинаковой сигнатурой.
  5. Мы можем использовать статические методы интерфейса java для удаления служебных классов, таких как коллекции, и переместить все его статические методы в соответствующий интерфейс, который было бы легко найти и использовать.

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

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

Была введена новая аннотация @Functional Interface для обозначения интерфейса как функционального интерфейса. Аннотация @Functional Interface-это средство, позволяющее избежать случайного добавления абстрактных методов в функциональные интерфейсы. Это необязательно, но хорошая практика, чтобы использовать его.

Функциональные интерфейсы-долгожданная и востребованная функция Java 8, поскольку она позволяет нам использовать лямбда-выражения для их создания. Добавлен новый пакет java.util.function с кучей функциональных интерфейсов, обеспечивающих целевые типы для лямбда-выражений и ссылок на методы. Мы рассмотрим функциональные интерфейсы и лямбда-выражения в будущих сообщениях.