Java default что это

Java default что это

+ статья в копилке. Но у меня есть вопрос: что будет если класс реализует 2 интерфейса, но у этих двух существует одинаковые методы?

А если в двух интерфейсах будет дефолтный метод с одинаковой сигнатурой, что тогда? Получаем проблему множественного наследования?

«Без множественного наследования возникает серьезная проблема: у одного и того же объекта может быть ряд разных характеристик и «поведений»». Не понял, может наоборот с множественным наследованием??

Жесть какая, но зачем. Нужны методы с каким-то поведением по-умолчанию — ну реализуй абстрактный класс. В java нет множественного наследования, но есть вот такие вот «поделки» в его сторону. По факту даю 146% что ни к чему хорошему в больших проектах это не приведет, просто даст новичкам больше свободы в написании говнокода.

Окей, а что случится, если мы реализуем в классе два интерфейса, но оба имеют дефолтный метод с одинаковым именем? Будет конфликт?

т.е. создать два обычных класса и если надо от них наследоваться писать implements a не extends? в самом классе писать вместо класс interface или не надо

JavaRush — это интерактивный онлайн-курс по изучению Java-программирования c нуля. Он содержит 1200 практических задач с проверкой решения в один клик, необходимый минимум теории по основам Java и мотивирующие фишки, которые помогут пройти курс до конца: игры, опросы, интересные проекты и статьи об эффективном обучении и карьере Java‑девелопера.

Этот веб-сайт использует данные cookie, чтобы настроить персонально под вас работу сервиса. Используя веб-сайт, вы даете согласие на применение данных cookie. Больше подробностей — в нашем Пользовательском соглашении.

Источник

Методы по умолчанию в Java 8: что могут и чего не могут?

Java-университет

Методы по умолчанию в Java 8: что могут и чего не могут? - 1

Перевод статьи, написанной Peter Verhas от апреля 2014 года. От переводчика: термин «default method» в Java только появился и я не уверен, есть ли для него устоявшийся перевод на русский. Я буду использовать термин «метод по умолчанию», хотя и не считаю его идеальным. Приглашаю к обсуждению относительно более удачного перевода.

Что такое метод по умолчанию

Теперь, с выходом Java 8, можно добавлять в интерфейсы новые методы так, что этот интерфейс остается совместимым с классами, которые его реализуют. Это очень важно, если вы разрабатываете библиотеку, которую используют множество программистов от Киева до Нью-Йорка. До выхода Java 8, если вы описали интерфейс в библиотеке, вы не могли добавлять в него методы не рискуя, что какое-нибудь приложение, работающее с вашим интерфейсом, не сломается при его обновлении. Так что, в Java 8 этого можно больше не бояться? Нет, нельзя. Добавление метода по умолчанию в интерфейс может привести к невозможности использования некоторых классов. Давайте сначала посмотрим на хорошие стороны методов по умолчанию. В Java 8 метод можно реализовать прямо в интерфейсе. (Статические методы в интерфейсе теперь тоже можно реализовывать, но это другая история.) Метод, реализованный в интерфейсе, называется методом по умолчанию и обозначается ключевым словом default. Если класс реализует интерфейс, он может, но не обязан, реализовать методы, реализованные в интерфейсе. Класс наследует реализацию по умолчанию. Вот почему не обязательно модифицировать классы при изменении интерфейса, который они реализуют.

Читайте также:  Span ID value in PHP

Множественное наследование?

Методы по умолчанию в Java 8: что могут и чего не могут? - 2

Все усложняется, если некий класс реализует более одного (скажем, два) интерфейса, а они реализуют один и тот же самый метод по умолчанию. Какой из методов унаследует класс? Ответ — никакой. В таком случае класс должен реализовать метод самостоятельно (напрямую, либо унаследовав его от другого класса). Ситуация аналогична, если только один интерфейс имеет метод по умолчанию, а в другом этот же метод является абстрактным. Java 8 старается быть дисциплинированной и избегать неоднозначных ситуаций. Если методы объявлены более чем в одном интерфейсе, то никакой реализации по умолчанию классом не наследуется — вы получите ошибку компиляции. Хотя, ошибку компиляции можно и не получить, если ваш класс уже скомпилирован. В этом отношении Java 8 недостаточно стойка. На то есть свои причины, в обсуждение которых я не хочу вдаваться (например: релиз Java уже вышел и время для дискуссий уже давно прошло и вообще, здесь для них не место).

  • Скажем, у вас есть два интерфейса, и класс реализует их оба.
  • Один из интерфейсов реализует метод по умолчанию m().
  • Вы компилируете все интерфейсы и класс.
  • Вы меняете интерфейс, в котором нет метода m(), объявляя его как абстрактный метод.
  • Компилируете только модифицированный интерфейс.
  • Запускаете класс.

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

  • измените интерфейс с абстрактным методом m() и добавьте реализацию по умолчанию.
  • Скомпилируйте модифицированный интерфейс.
  • Запустите класс: ошибка.

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

Читайте также:  Testing Title

Пример кода

Для того, что бы продемонстрировать вышесказанное, я создал тестовый каталог для класс C.java и 3 подкаталога для интерфейсов в файлах I1.java и I2.java. Корневой каталог для теста содержит исходный код класса C.java. Каталог base содержит версию интерфейсов, которые подходят для выполнения и компиляции: интерфейс I1 имеет метод по умолчанию m(); интерфейс I2 пока не имеет никаких методов. В классе есть метод main , так что мы можем выполнить его для проверки. Он проверяет, если ли какие-то аргументы командной строки, так что мы легко можем выполнить его как с вызовом, так и без вызова метода m() .

 ~/github/test$ cat C.java public class C implements I1, I2 < public static void main(String[] args) < C c = new C(); if( args.length == 0 )< c.m(); >> > ~/github/test$ cat base/I1.java public interface I1 < default void m()< System.out.println("hello interface 1"); >> ~/github/test$ cat base/I2.java public interface I2
 ~/github/test$ javac -cp .:base C.java ~/github/test$ java -cp .:base C hello interface 1 

Каталог compatible содержит версию интерфейса I2, который объявляет метод m() абстрактным, а также, по техническим причинам, не измененную копию I1.java.

 ~/github/test$ cat compatible/I2.java public interface I2
 ~/github/test$ javac -cp .:compatible C.java C.java:1: error: C is not abstract and does not override abstract method m() in I2 public class C implements I1, I2 < ^ 1 error 

Сообщение об ошибке очень точное. Тем не менее, у нас есть C.class с предыдущей компиляции и, если мы скомпилируем интерфейсы в каталог compatible, у нас будет два интерфейса , которые все еще можно использовать для запуска класса:

 ~/github/test$ javac compatible/I*.java ~/github/test$ java -cp .:compatible C hello interface 1 
 ~/github/test$ cat wrong/I2.java public interface I2 < default void m()< System.out.println("hello interface 2"); >> 

Можно даже не мучиться с компиляцией. Несмотря на то, что метод объявлен дважды, класс все еще может использоваться и работать, пока не произойдет вызов метода m(). Вот для чего нам нужен аргумент командной строки:

 ~/github/test$ javac wrong/*.java ~/github/test$ java -cp .:wrong C Exception in thread "main" java.lang.IncompatibleClassChangeError: Conflicting default methods: I1.m I2.m at C.m(C.java) at C.main(C.java:5) ~/github/test$ java -cp .:wrong C x ~/github/test$ 

Заключение

Когда вы переносите вашу библиотеку в Java 8 и меняете ваши интерфейсы, добавляя в них методы по умолчанию, скорее всего, проблем у вас не возникнет. Во всяком случае, на это надеются разработчики библиотек для Java 8, добавляя функцональность. Приложения, использующие вашу библиотеку, пока используют ее для Java 7, где нет методов по умолчанию. Если несколько библиотек используются вместе, вероятность конфликта есть. Как его избежать? Проектируйте API вашей библиотеки так же, как и раньше. Не расслабляйтесь, полагаясь на возможности методов по умолчанию. Они - это крайнее средство. Тщательно выбирайте имена, что бы избежать коллизий с другими интерфейсами. Посмотрим, как будет развиваться разработка для Java с использованием этой фичи.

Читайте также:  What is manifest file in java

Источник

Оцените статью