Java 8. Заводская модель. Абстрактный класс vs интерфейс со стандартным методом [duplicate]

Попробуйте

в соответствии с документами:

Объекты символов и обозначают пространство en и em пространство соответственно, где пространство en равно половине размера точки, а пространство em равно размеру текущего шрифта. Для шрифтов с фиксированным шагом пользовательский агент может обрабатывать пространство en как эквивалент символа пробела, а пространство em равнозначно двум символам пробела.

Ссылка на документы: https://www.w3.org/MarkUp/html3/specialchars.html

358
задан Ravindra babu 17 September 2016 в 18:17
поделиться

13 ответов

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

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

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

213
ответ дан Marko Topolnik 15 August 2018 в 15:16
поделиться
  • 1
    По этим соображениям следующее, что они добавят, - это объявления метода по умолчанию. Я до сих пор не уверен в этом, эта функция кажется скорее хаком для меня, которая подвергается всем людям за неправильное использование. – panther 16 February 2015 в 19:47
  • 2
    Единственное использование абстрактных классов в Java 8-й эре, которое я вижу, - это определение нефинализированных полей. В интерфейсах поля по умолчанию являются окончательными, поэтому вы не можете их изменить после их назначения. – Anuroop 17 September 2017 в 09:41
  • 3
    – Marko Topolnik 17 September 2017 в 09:42
  • 4
    @Anuroop Не только по умолчанию --- это единственный вариант. Интерфейсы не могут объявлять состояние экземпляра, поэтому абстрактные классы здесь остаются. – Marko Topolnik 17 September 2017 в 09:47
  • 5
    @PhilipRego Абстрактные методы не называют ничего, потому что они не имеют реализации. Внедренные методы в классе могут обращаться к состоянию класса (переменные экземпляра). Интерфейсы не могут объявить их, поэтому методы по умолчанию не могут получить к ним доступ. Они должны полагаться на класс, предоставляющий реализованный метод, который обращается к состоянию. – Marko Topolnik 27 February 2018 в 21:13

Эти два варианта совершенно разные:

Способы по умолчанию включают добавление внешних функций к существующим классам без изменения их состояния.

И абстрактные классы являются обычным типом наследования, они нормальные классы, которые должны быть расширены.

13
ответ дан Andrey Chaschev 15 August 2018 в 15:16
поделиться

Что касается вашего запроса

Итак, когда следует использовать интерфейс с методами по умолчанию и когда должен использоваться абстрактный класс? Являются ли абстрактные классы еще полезными в этом сценарии?

Документация java обеспечивает идеальный ответ.

Абстрактные классы по сравнению с интерфейсами:

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

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

С интерфейсами все поля автоматически публикуются , static и final, а все методы, которые вы объявляете или определяете (как методы по умолчанию), являются общедоступными. Кроме того, вы можете расширить только один класс, независимо от того, является он абстрактным, тогда как вы можете реализовать любое количество интерфейсов.

Варианты использования для каждого из них были объяснены ниже в сообщении SE :

В чем разница между интерфейсом и абстрактным классом?

Являются ли абстрактные классы полезными в этом сценарии?

Да. Они по-прежнему полезны. Они могут содержать нестатические, не конечные методы и атрибуты ( protected, private в дополнение к public ), что невозможно даже при использовании интерфейсов Java-8.

10
ответ дан Community 15 August 2018 в 15:16
поделиться

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

  1. Методы по умолчанию положили конец классическим образ интерфейса и сопутствующий класс, который реализует большинство или все методы в этом интерфейсе. Примером является Collection and AbstractCollection. Теперь мы должны реализовать методы в самом интерфейсе, чтобы обеспечить функциональность по умолчанию. Классы, реализующие интерфейс, имеют выбор, чтобы переопределить методы или наследовать реализацию по умолчанию.
  2. Еще одно важное использование методов по умолчанию - interface evolution. Предположим, что у меня был класс Ball as: public class Ball implements Collection { ... }

Теперь в Java 8 появились новые потоки функций. Мы можем получить поток, используя stream метод, добавленный в интерфейс. Если stream не были методом по умолчанию, все реализации для интерфейса Collection сломались, поскольку они не будут реализовывать этот новый метод. Добавление метода не по умолчанию к интерфейсу не source-compatible.

Но предположим, что мы не перекомпилируем класс и не используем старый файл jar, который содержит этот класс Ball. Класс будет загружаться без этого отсутствующего метода, экземпляры могут быть созданы, и кажется, что все работает нормально. НО, если программа вызывает метод stream, например Ball, мы получим AbstractMethodError. Поэтому решение метода по умолчанию решило обе проблемы.

10
ответ дан i_am_zero 15 August 2018 в 15:16
поделиться

Это описано в этой статье . Подумайте о forEach коллекций.

List<?> list = …
list.forEach(…);

Функция forEach еще не объявлена ​​интерфейсом java.util.List и java.util.Collection. Одним из очевидных решений было бы просто добавить новый метод к существующему интерфейсу и обеспечить реализацию там, где это требуется в JDK. Однако после опубликования невозможно добавить методы к интерфейсу без нарушения существующей реализации.

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

53
ответ дан Masudul 15 August 2018 в 15:16
поделиться
  • 1
    «невозможно добавить методы к интерфейсу без нарушения существующей реализации» - не так ли? – Andrey Chaschev 15 November 2013 в 12:27
  • 2
    @AndreyChaschev Если вы добавите новый метод в интерфейс, тогда все разработчики должны реализовать этот новый метод. Поэтому он нарушает существующие реализации. – Marko Topolnik 15 November 2013 в 12:31
  • 3
    @MarkoTopolnik благодарит, пропустил это. Просто упомянем, что существует способ частично избежать этого - путем представления этого метода в абстрактной реализации по умолчанию. Для этого примера это AbstractList::forEach выбрасывает UnsupportedOperationException. – Andrey Chaschev 15 November 2013 в 12:39
  • 4
    @AndreyChaschev Да, это был старый способ (khm ... - текущий способ :), с недостатком, который ограничивает его реализацию на единичное наследование из предоставленной абстрактной реализации. – Marko Topolnik 15 November 2013 в 12:43

@ narendra-pathai: Пожалуйста, сначала подумайте о принципе open / closed. Методы по умолчанию в интерфейсах DO VIOLATE. Это плохая функция Java. Это поощряет плохой дизайн, плохую архитектуру, низкое качество программного обеспечения. Я предлагаю полностью избегать использования методов по умолчанию.

Задайте себе несколько вопросов: - Почему вы не можете поместить свои методы в абстрактный класс? Вам понадобится более одного абстрактного класса? Тогда подумайте о том, за что отвечает ваш класс. Вы уверены, что все методы, которые вы собираетесь применить к одному классу, действительно выполняют ту же цель? Возможно, вы выделите несколько целей, а затем разделите свой класс на несколько классов, для каждой цели - собственный класс.

0
ответ дан mentallurg 15 August 2018 в 15:16
поделиться

Правило Remi Forax : вы не создаете абстрактные классы. Вы разрабатываете приложение с помощью интерфейсов. Независимо от того, является ли версия Java, каков бы ни был язык. Это подтверждается принципом сегрегации I nterface в принципах SOLID .

Вы можете использовать абстрактные классы для факторизации кода. Теперь с Java 8 вы можете сделать это прямо в интерфейсе. Это объект, не более.

4
ответ дан Nicolas Zozol 15 August 2018 в 15:16
поделиться

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

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

Факты & amp; Ограничения:

1-May могут быть объявлены только в интерфейсе, а не в классе или абстрактном классе.

2-Должен предоставить тело

3-It не считается абстрактным, как другие обычные методы, используемые в интерфейсе.

1
ответ дан Sanie 15 August 2018 в 15:16
поделиться

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

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

1
ответ дан shubh 15 August 2018 в 15:16
поделиться

Как описано в этой статье,

Абстрактные классы и интерфейсы в Java 8

После введения метода по умолчанию кажется, что интерфейсы и абстрактные классы одинаковы. Тем не менее, они по-прежнему отличаются концепцией в Java 8.

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

9
ответ дан Sufiyan Ghori 15 August 2018 в 15:16
поделиться

Способы по умолчанию в интерфейсе Java позволяют реализовать эволюцию интерфейса .

Учитывая существующий интерфейс, если вы хотите добавить к нему метод, не нарушая бинарную совместимость со старыми версиями интерфейса, у вас есть два варианта: добавьте стандартный или статический метод. Действительно, любой абстрактный метод, добавленный в интерфейс, должен быть реализован классами или интерфейсами, реализующими этот интерфейс.

Статический метод уникален для класса. Метод по умолчанию уникален для экземпляра класса.

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

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

Подробнее о теме здесь .

5
ответ дан The Guy with The Hat 15 August 2018 в 15:16
поделиться

Почему мы должны использовать абстрактный класс:

  1. Абстрактный класс может иметь абстрактные и не абстрактные методы.
  2. Абстрактный класс не поддерживает множественное наследование.
  3. Абстрактный класс может иметь конечные, не конечные, статические и нестатические переменные.
  4. Абстрактный класс может иметь статические методы, основной метод и конструктор.
  5. Абстрактный класс может обеспечить реализацию интерфейса.
  6. Ключевое слово abstract используется для объявления абстрактного класса.

Почему мы должны использовать интерфейс:

  1. Интерфейс - это наиболее абстрактный уровень дизайна вашего приложения
  2. . Интерфейс поддерживает множественное наследование.
  3. Интерфейс, созданный только для описания сигнатур для подклассов
  4. Интерфейс имеет только статические и конечные переменные.
  5. Использовать метод по умолчанию только для расширения некоторых интерфейсов, например внешней библиотеки. Но в основном это не очень хорошая практика:)
4
ответ дан Unheilig 15 August 2018 в 15:16
поделиться

Есть несколько технических отличий. Абстрактные классы могут по-прежнему делать больше по сравнению с интерфейсами Java 8:

  1. Абстрактный класс может иметь конструктор.
  2. Абстрактные классы более структурированы и могут содержать состояние.

Концептуально основной целью методов защиты является обратная совместимость после внедрения новых функций (в виде лямбда-функций) в Java 8.

87
ответ дан Vadym Vasyliev 15 August 2018 в 15:16
поделиться
  • 1
  • 2
    Conceptually, main purpose of defender methods is a backward compatibility after introduction of new features (as lambda-functions) in Java 8. вы можете объяснить это, пожалуйста? – Asif Mushtaq 9 March 2016 в 14:46
  • 3
    @UnKnown эта страница дает больше информации: docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html – bernie 14 June 2016 в 14:22
  • 4
    – LegendLength 15 July 2017 в 07:15
  • 5
    Более тонкий пункт о точке нет. 2 выше примерно "может содержать состояние, это". Абстрактные классы могут содержать состояние, которое может быть изменено позже. Интерфейсы также могут содержать состояние, но как только состояние назначается после создания экземпляра, состояние не может быть изменено. – Anuroop 17 September 2017 в 09:43
Другие вопросы по тегам:

Похожие вопросы: