Подтвердить что ты не робот

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

Это цитируемый вопрос из учебных материалов моего университета.

Мне это совершенно не имеет смысла.

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

Например, приложение имеет "on before shutdown hook", я могу зарегистрировать мой метод обратного вызова там, который сохраняет пользовательские данные на диске до выключения.

Абстрактные методы объясняются сами собой.

Для меня это совсем другое? или у любой из этих вещей есть второй смысл, о котором я не знаю? Я сделал быстрый поиск, но ничего не нашел.

4b9b3361

Ответ 1

Лично я пошел к профессору и попросил разъяснения перед тем, как спросить сообщество StackOverflow.

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

Ответ 2

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

public abstract class AbstractActionDoer() {
    public void doAction(Action act) {
        beforeAction();
        act.do();
        afterAction();
    }
    protected abstract void beforeAction();
    protected abstract void afterAtion();
}

public class DefaultActionDoer() extends AbstractActionDoer {
    public void doAction(Action act) {
        beforeAction();
        act.do();
        afterAction();
    }
    // default empty implementation
    protected void beforeAction() { }
    protected void afterAtion() { }
}

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

Ответ 3

Было определенно некоторое сочетание концепций с деталями реализации.

В принципе, ваше понимание правильное.

Чтобы процитировать выражение OP, , что:

Крючки - это определенные точки, где разработчик может указать методы или обратные вызовы, которые должны быть выполнены.

Язык Javascript - это, пожалуй, самый (печально известный) язык, позволяющий подключать все. (В качестве примечания: у Google была дыра в безопасности, в которой был задействован конструктор Javascript Array)

Реализация интерфейса абстрактного метода/обратного вызова - это механизм , как обратный вызов реализуется в Java-коде.

Ответ 4

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

Ответ 5

Для меня это совсем другое?

Это оба способа отложить код до класса клиента (пользователя вашего класса):

1) Определите абстрактный метод

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

2) Определите крючок

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

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


Это, вероятно, слишком много информации, но в программировании для Android вы видите оба:

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

http://developer.android.com/reference/android/widget/CursorAdapter.html

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


Однако подкласс CursorAdapter равен SimpleCursorAdapter

http://developer.android.com/reference/android/widget/SimpleCursorAdapter.html

Этот класс реализует newView и bindView и выбирает интерфейс ViewBinder, который клиенты могут реализовать и зарегистрировать в экземпляре SimpleCursorAdapter. Экземпляр ViewBinder должен предоставить метод setViewValue, который связывает конкретную часть данных с конкретным виджетами пользовательского интерфейса.

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

Ответ 6

Крюк - это старый термин, возможно, встречающийся до 1980-х годов. Из вашего вопроса неясно, применимо ли "в Java" как к "Крюкам", так и к абстрактным методам, но если бы я был профессором (!), Я бы подумал, что важно понять историю крючков (до Java).

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

Вот несколько определений, найденных в http://www.tldp.org/LDP/Linux-Dictionary/html/h.html

Hook

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

крюк

п. Программная или аппаратная функция, включенная для упрощения последующих дополнений или изменений пользователем. Например, простая программа, которая печатает числа, может всегда печатать их в базе 10, но более гибкая версия позволит переменной определить, какую базу использовать; установка переменной в 5 приведет к тому, что программа напечатает цифры в базе 5. Эта переменная представляет собой простой крючок. Еще более гибкая программа может исследовать переменную и обрабатывать значение 16 или менее в качестве базы для использования, но обрабатывать любое другое число как адрес предоставленной пользователем процедуры для печати числа. Это волосатый, но мощный крюк; затем можно написать рутину для печати чисел как римских цифр, например, или ивритских символов, и подключить их к программе через крючок. Часто разница между хорошей программой и превосходной состоит в том, что у последнего есть полезные крючки в разумно выбранных местах. Оба могут выполнять оригинальную работу одинаково хорошо, но тот, у кого есть крючки, гораздо более гибкий для будущего расширения возможностей (например, EMACS - это все крючки). Термин "пользовательский выход" является синонимом, но гораздо более формальным и менее хакерским. Из словаря жаргона

крюк

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


Что касается Абстрактных методов в Java, это было хорошо объяснено в Bert F answer. Я подчеркиваю, что в отличие от общего понятия крючков (что позволяет настраивать) абстрактные методы требуют спецификации, то есть определения по умолчанию не существует.