Почему HTTPServlet является абстрактным классом? Любая функциональная причина?

HttpServlet - абстрактный класс со всеми реализованными методами. Почему он абстрактный?

Самый общий ответ, который я получил, - это ограничение экземпляра HttpServlet. Но есть и другие способы сделать это, так как частный конструктор будет ограничивать создание экземпляра.

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

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

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

Да, сочетание абстрактных и конкретных методов в порядке.

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

В этом случае doGet() или doPost().

Ответ 1

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

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

Конструкция HttpServlet была, вероятно, не идеальной - как на многих страницах, особенно в формах, логика GET и POST должна протекать хотя бы частично по общему пути. Однако идея дизайна HttpServlet заключалась в том, чтобы предложить версии doGet(), doPost() и т.д., Отвечающие на ошибку "не поддерживается" в зависимости от версии HTTP. Эти заглушки были бы полезны для наследования, если бы вам нужно было вернуть такой ответ.

В заключение, API/интерфейс завершен, но функциональность окончательно нет. Таким образом, он объявляется абстрактным.

Ответ 2

HTTPServlet - это абстрактный класс со всеми реализованными методами. Тогда почему это абстрактно?

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

Подкласс HttpServlet должен переопределять хотя бы один метод, обычно один из следующих:

  • doGet, если сервлет поддерживает HTTP-запросы GET
  • doPost, для запросов HTTP POST
  • doPut, для запросов HTTP PUT
  • doDelete, для запросов HTTP DELETE
  • init и destroy, чтобы управлять ресурсами, которые хранятся в течение срока службы сервлета
  • getServletInfo, который сервлет использует для предоставления информации о себе

Если вы расширяете класс без переопределения любых методов, вы получите бесполезный сервлет; то есть тот, который дает ответ об ошибке для всех запросов. Точно так же, если класс не был abstract, то любой прямой экземпляр HttpServlet был бы бесполезен.

Следовательно, причиной создания HttpServlet class abstract является предотвращение (наивной) ошибки программиста.


Для записи причина предоставления реализаций всех методов заключается в том, чтобы сделать жизнь проще для программиста, предоставляя поведение по умолчанию. Например, если я не хочу, чтобы мой сервлет поддерживал запросы DELETE, реализация по умолчанию для doDelete будет удобно отправлять ответ с кодом ответа "Метод не поддерживается".

Ответ 3

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

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

http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html

Причина: Мы все знаем, что HttpServlet не имеет абстрактного метода. Он содержит все конкретные методы. Но этот класс остается абстрактным. Причина очень проста. Наш собственный класс может выступать в роли сервлета, только когда он расширяет класс HttpServlet или GenericServlet или реализует интерфейс Servlet                          Если класс HttpServlet не будет оставаться абстрактным, вам не будет предложено расширить этот класс, и ваш класс не будет действовать как Servlet.

ServletContainer использует instanceOf(), чтобы узнать, является ли ваш класс дочерним по отношению к интерфейсу HttpServlet или GenericServlet или Servlet.                                 Поскольку ваш класс не является дочерним по отношению к классу HttpServlet, GenericServlet или внедренному сервлет-интерфейсу, instanceOf() завершится с ошибкой.

Ответ 4

В принципе, мы имеем здесь абстрактный класс (HttpServlet) без абстрактного метода или только конкретного метода. Где наш класс сервлета реализует javax.servlet.Servlet напрямую (в случае RMI и CORBA) или косвенно (расширение общего или HttpServlet).

Как интерфейс имеет 3 основных метода (init(), service() и destroy()), который реализуется HttpServlet (абстрактный класс), который расширяется вашим классом сервлета, который обрабатывает запросы браузера, сделанные на сервер используя эти три метода. И в зависимости от типа метода HTTP-запроса наш класс сервлета (путем расширения HttpServlet) использует соответствующий метод do[xxx], который в большинстве случаев равен doGet или doPost. Если у нас есть все методы или некоторые методы httpServlet как абстрактный метод, мы должны реализовать весь или некоторый абстрактный метод, который присутствует в HttpServlet в нашем подклассе сервлета, но мы должны реализовать только те методы, которые необходимы для обрабатывать запрос метода HTTP. Таким образом, по моему мнению, конкретный метод в абстрактном классе обеспечивает свободу реализации в зависимости от логики HTTP-запроса.

Ответ 5

Есть две причины для этого.

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

Ответ 6

В основном HttpServlet не содержит абстрактного метода, его единственный метод службы жизненного цикла (-, -), который является абстрактным. А также предоставляет 7 doXXX() не абстрактных методов, не имея никакой прикладной логики для отправки ошибки 404 в качестве ответа. Таким образом, расширенный класс класса HTTPServlet не нуждается в реализации doXXX() методов чтобы сообщить разработчикам Java, что класс HttpServlet не полностью реализован класс класса HttpServlet, сделанный как абстрактный.