Перейти к содержимому

Default java что это

  • автор:

Зачем нужно ключевое слово default?

Изначально (с Java 1.5) это слово использовалось для объявления дефолтного значения элементов аннотации.

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

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

В реализации такого метода его дефолтный вариант вызывается тем же синтаксисом, что и внешний класс из вложенного: InterfaceName.super.methodName() .

Методы по умолчанию подошли еще на шаг к введению в Java беспроблемной версии множественного наследования – примесям (mixin). Интерфейс не может иметь состояния, поэтому полноценные примеси всё ещё недоступны.

Разница между методом по умолчанию в интерфейсе и обычным методом в классе

Метод по умолчанию представляет собой метод, который объявлен в интерфейсе с модификатором default ; его тело всегда представлено блоком. Он предоставляет реализацию по умолчанию для любого класса, который реализует интерфейс без перекрытия метода. Методы по умолчанию отличны от конкретных методов, которые объявляются в классах.

Отслеживать
22k 3 3 золотых знака 27 27 серебряных знаков 37 37 бронзовых знаков
задан 31 янв 2017 в 23:11
8,460 4 4 золотых знака 25 25 серебряных знаков 62 62 бронзовых знака

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

default метод не может обращаться к состоянию объекта (полям объекта), так как никакого объекта нет, но может вызвать другие методы и обращаться к статическим данным (константам).

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

В классе, реализующим интерфейс с default методами, вы можете их переопределить.

interface I1 < // это public static final int i = 0; // но в описании интерфейса public static final можно опустить int i = 0; default void m1() < System.out.println("I1 m1 i C1 m2"); >public static void main(String[] args) < new C1().m1(); new C1().m2(); >> 

Вывод будет следующим:

I1 m1 i = 0 C1 m2 C1 m2 

Отслеживать
ответ дан 31 янв 2017 в 23:22
Mikhail Vaysman Mikhail Vaysman
14.2k 1 1 золотой знак 21 21 серебряный знак 31 31 бронзовый знак

многие начинающие забывают, что у интерфейса нет доступа к state (состоянию). поэтому я это и упомянул. в данном случае — это фигура речи.

1 фев 2017 в 0:05

Одно из различий заключается в том, что все методы (в т.ч. и default ) в интерфейсе неявно объявлены как public и поменять этот модификатор доступа не получится, а в обычном методе в классе Вы можете сами устанавливать различные модификаторы доступа.

UPD:

Метод по умолчанию представляет собой метод, который объявлен в интерфейсе с модификатором default; его тело всегда представлено блоком. Он предоставляет реализацию по умолчанию для любого класса, который реализует интерфейс без перекрытия метода. Методы по умолчанию отличны от конкретных методов, которые объявляются в классах.

Вы несколько неправильно поняли это предложение. Здесь имелось ввиду то, что если класс реализует интерфейс, который содержит default -метод, то при переопределении в классе этого метода, метод из класса перекроет default -реализацию.

Попробуйте сделать акцент на выделенном тексте, тогда поймете о чем я:

Он предоставляет реализацию по умолчанию для любого класса, который реализует интерфейс без перекрытия метода. Методы по умолчанию отличны от конкретных методов, которые объявляются в классах.

К тому же, если бы здесь имелись ввиду какие-то принципиальные различия, то они здесь же были бы указаны, так как в этом пункте из главы про интерфейсы рассказывается непосредственно про default -методы.

Java 8 Default и Static методы

В Java 8 появилась возможность писать методы с реализацией в интерфейсах. Такие методы называются default и static. Особенности работы с ними мы сегодня и рассмотрим.

2. Default методы

Объявляются такие методы следующим образом

interface Human < default void walk ( ) < System . out . println ( "Ну, я пошел. " ) ;

Использовать их можно только после получения экземпляра

Human . walk ( ) ; //ошибка, так делать нельзя
Human human = new Human ( ) < >;
human . walk ( ) ; //а вот так можно

Default методы так же можно переопределять как и обычные методы

class Runner implements Human < public void walk ( ) < System . out . println ( "Я бегу" ) ;

Но есть один нюанс, рассмотрим следующий случай

interface Human < default void walk ( ) < System . out . println ( "Ну, я пошел. " ) ; interface Walkable < default void walk ( ) < System . out . println ( "Ходьба" ) ; class Runner implements Human , Walkable <

В данном случае мы получим ошибку компиляции, ибо нельзя наследовать одновременно несколько default методов, не понятно какой из методов вызывать, если мы напишем следующий код

Runner runner = new Runner ( ) ;
runner . walk ( ) ;

3. Static методы

C ними все проще, чем с default методами. Static методы в интерфейсе работают точно так же как и static методы в классе.

static void walk ( ) < System . out . println ( "Ну, я пошел. " ) ; Human . walk ( ) ;

Наследовать static методы в интерфейсе нельзя, как и static методы в классах.

Так же нельзя вызывать static метод интерфейса из класса наследника

public static void main ( String [ ] args ) < HomoSapiens . walk ( ) ; //ошибка компиляции interface Human < static void walk ( ) < System . out . println ( "Ну, я пошел. " ) ; class HomoSapiens implements Human <

В Java 8 есть еще множество полезных нововведений, которые можно найти тут

Есть возможность записаться на наши курсы по Java. Детальную информацию смотрите у нас на сайте.

  • ← Найти максимальный элемент в массиве из сгенерированных чисел
  • Заменить каждый элемент массива с нечетным индексом на ноль →

Defaut method в Java

Default-методы появились Java 8. В это статье рассказывается, что это такое, зачем появилось, и как ими пользоваться.

Default-метод — это метод, который реализуется прямо в интерфейсе, его помечают ключевым словом default.

Читайте также про Модификаторы доступа

Пример использования

Допустим, у нас есть интерфейс Animal:

public interface Animal

Есть классы Cat и Fish, реализующие интерфейс Animal:

public class Cat implements Animal < @Override public String move() < return "run"; >>
public class Fish implements Animal < @Override public String move() < return "swim"; >>

Мы хотим добавить в интерфейс Animal метод sleep(), при этом не реализовывать его в каждом классе, а реализовать непосредственно в интерфейсе. Классы же будут наследовать этот метод по умолчанию. Для этого наш метод надо обозначить как default:

public interface Animal < String move(); default String sleep() < return ("sleep"); >>

Теперь этот метод унаследуют все животные:

@Test public void whenCatSleep_thenOk()

Впрочем, его можно и переопределить в каком-либо из классов, например в Fish:

public class Fish implements Animal < @Override public String move() < return "swim"; >@Override public String sleep() < return "fish sleeps"; >>

Убедимся, что рыба спит по-своему:

@Test public void whenFishSleep_thenOnItsOwn()

Как наследуются default-методы

Возникает вопрос, какой метод унаследует класс, реализующий два интерфейса, если оба из них содержат default-методы с одинаковыми именами.

Например, есть второй интерфейс Man, который тоже содержит свой default метод sleep():

public interface Man < default String sleep() < return ("man sleeps"); >>

И есть класс Kentavr, реализующий как интерфейс Man, так и Animal. Какой же метод sleep() унаследует Kentavr?

Чтобы не было неопределенности (и чтобы скомпилировался код), мы обязаны переопределить в Kentavr метод sleep(), причем можно просто вызвать в нем метод sleep() любого из интерфейсов — Man либо Animal, указав через точку и super, чей именно метод нужен:

public class Kentavr implements Man, Animal < @Override public String move() < return "kentavr moves"; >@Override public String sleep() < return Man.super.sleep(); >>

Убедимся, что кентавр спит по-человечески:

@Test public void whenKentavrSleep_thenSpecifyWhose()

Причины появления default-методов

Наверно уже понятно, что default-методы упрощают рефакторинг — а именно, добавление новых методов.

До Java 8 все методы в интерфейсах были абстрактными. К чему это вело?

К тому, что при добавлении нового метода в интерфейс приходилось править все классы, реализующие интерфейс — реализовывать метод в этих классах. Это было неудобно. А в Java 8 (в классы ядра) захотели ввести новые методы в старые интерфейсы. Так что ввели ключевое слово default и эти методы сделали default. Например, в интерфейсе java.lang.Iterable появились новые default-методы forEach() и spliterator():

public interface Iterable  < Iteratoriterator(); default void forEach(Consumer action) < Objects.requireNonNull(action); for (T t : this) < action.accept(t); >> default Spliterator spliterator() < return Spliterators.spliteratorUnknownSize(iterator(), 0); >>

Поскольку огромное число классов реализуют Iterable , без default-методов дополнить этот интерфейс было бы практически невозможно.

Итог

Мы рассмотрели, что такое default метод в Java. Код примеров доступен на GitHub.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *