Почему 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, сделанный как абстрактный.