Абстрактный класс со всеми конкретными методами - PullRequest
16 голосов
/ 12 декабря 2008

Существуют ли практические ситуации программирования, когда кто-то может объявить абстрактный класс, когда все методы в нем конкретны?

Ответы [ 9 ]

15 голосов
/ 12 декабря 2008

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

(И да, мне не нравится шаблон метода шаблона;))

5 голосов
/ 12 декабря 2008

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

4 голосов
/ 12 декабря 2008

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

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

2 голосов
/ 13 декабря 2008

Предыдущие ответы уже затронули основные вопросы, но есть небольшая деталь, о которой стоит упомянуть.

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

2 голосов
/ 12 декабря 2008

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

public interface Foo {
    public void bar();
}
public abstract class FooDecorator implements Foo {
    private final Foo wrapped;
    public FooDecorator(Foo wrapped) { this.wrapped = wrapped; }
    public void bar() { wrapped.bar(); }
}
public class TracingFoo extends FooDecorator {
    //Omitting constructor code...
    public void bar() {
        log("Entering bar()");
        super.bar();
        log("Exiting bar()");
    }
}

Хотя я не вижу необходимости объявлять FooDecorator абстрактным (неабстрактный пример: HttpServletRequestWrapper ).

1 голос
/ 18 июня 2013

Интересно, почему никто не указал на практический пример MouseAdapter:

http://docs.oracle.com/javase/6/docs/api/java/awt/event/MouseAdapter.html

Абстрактный класс адаптера для получения событий мыши. Методы в этот класс пуст. Этот класс существует как удобство для создания объекты слушателя.

0 голосов
/ 06 августа 2018

Пример сервлета:

Все методы являются конкретными, но базовый класс сам по себе бесполезен:

DeleteAuthor.java

  1. Абстрактный класс с конкретным методом doGet.
  2. Файл вызовов doGet, указанный в защищенном строке sql_path.
  3. sql_path равен нулю .

DeleteAuthor Keep Book.java

  1. расширяет абстрактный класс DeleteAuthor
  2. устанавливает для sql_path значение delete_author_ KEEP _BOOK.sql

DeleteAuthor Запись Book.java

  1. расширяет абстрактный класс DeleteAuthor
  2. устанавливает для sql_path значение delete_author_ BURN _BOOK.sql
0 голосов
/ 12 декабря 2008

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

  • этот класс является родителем многих классов системы;
  • это имеет большую ответственность (методы, используемые многими классами) для требований домена;
  • этот класс не представляет собой конкретный объект;
0 голосов
/ 12 декабря 2008

Хороший вопрос:)

Одно можно сказать наверняка ... это, безусловно, возможно. Предложение шаблона от krosenvold является одной из веских причин для этого.

Я просто хочу сказать, что класс не должен быть объявлен abstract только для предотвращения его создания.

Это указано в Спецификации языка Java Раздел 8.1.1.1

...