14

HttpServlet是一个包含所有实现方法的抽象类。为什么是抽象的?

我得到的最常见的答案是,限制HttpServlet. 但是还有其他方法可以做到这一点,例如私有构造函数将限制实例化。

我可以理解他们遵循模板方法设计模式。如果某些方法是抽象的,用户最终将实现所有这些方法,即使他的业务逻辑不需要它们。

但是如果HttpServlet不是抽象的,用户仍然可以扩展它并覆盖 require 方法。

至少按照“抽象”这个词的字典含义,拥有一个包含所有已实现方法的抽象类对我来说没有任何意义。

是的,抽象和具体方法的组合是可以的。

但是,如果您要创建一个类抽象,为什么不将子类必须重写的那些方法抽象化呢?或者可能根本不将其声明为抽象?

喜欢doGet()还是doPost()这种情况。

4

6 回答 6

13

要获得任何有用的行为,您必须重写这些方法。HttpServlet 本身没有有用的功能。

将其构造函数设为私有将限制创建子类的能力。

HttpServlet 的设计可能并不理想——因为在许多页面上,尤其是表单上,GET 和 POST 逻辑至少部分应该沿着共同的路径进行。然而,HttpServlet 的设计理念是提供等实现doGet()doPost()根据 HTTP 版本回答“不支持”错误。如果您需要返回这样的答案,这些存根对继承很有用。

总之,API/接口是完整的——但功能肯定是不完整的。因此它被声明为abstract

于 2013-09-20T05:14:09.627 回答
9

HTTPServlet 是一个包含所有实现方法的抽象类。那为什么是抽象的呢?

它是抽象的,因为关键方法的实现必须由自定义 servlet 类提供(例如,被覆盖)。正如javadoc所说:

HttpServlet 的子类必须覆盖至少一种方法,通常是以下其中一种:

  • doGet,如果 servlet 支持 HTTP GET 请求
  • doPost,用于 HTTP POST 请求
  • doPut,用于 HTTP PUT 请求
  • doDelete,用于 HTTP DELETE 请求
  • init 和 destroy,用于管理 servlet 生命周期内持有的资源
  • getServletInfo,servlet 用来提供有关自身的信息

如果你扩展类而不重写任何方法,你将得到一个无用的 servlet;即对所有请求给出错误响应的一种。同样,如果类不是abstract,那么任何直接的实例HttpServlet都是无用的。

因此,创建HttpServlet类的原因abstract是为了防止(天真的)程序员错误。


为了记录,提供所有方法的实现的原因是通过提供默认行为使程序员的生活更简单。例如,如果我不希望我的 servlet 支持 DELETE 请求,则默认实现doDelete将方便地发送带有“方法不支持”响应代码的响应。

于 2013-09-20T05:37:03.610 回答
2

您被迫扩展 HttpServlet,因为您需要向其中添加特定于应用程序的逻辑。这是根据 oracle 的人对抽象类的定义:

“抽象类是被声明为抽象的类——它可能包含也可能不包含抽象方法。抽象类不能被实例化,但它们可以被子类化。”

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

原因:我们都知道HttpServlet没有任何抽象方法。它包含了所有具体的方法。但是这个类仍然是抽象的。原因很简单。我们自己的类可以作为一个Servlet,只有当它扩展了HttpServlet或者GenericServlet类,或者实现了Servlet接口如果HttpServlet类不保持抽象,你就没有兴趣去扩展这个类,你的类也不能作为Servlet。

ServletContainer 使用 instanceOf() 来了解您的类是否是 HttpServlet 或 GenericServlet 或 Servlet 接口的子类。由于您的类不是 HttpServlet、GenericServlet 类或实现的 Servlet 接口的子类,instanceOf() 将失败。

于 2014-11-24T20:39:55.583 回答
-2

这有两个原因。

  1. 首先,您不能创建 HttpServlet 类的对象。假设它没有受到保护,那么我们可以创建这个类的 obj ,这将是无用的。
  2. 其次,HttpServlet 类中有受保护的方法。因此,要访问一个类的受保护事物以便在您的实现类中具有 Servlet 功能,您必须扩展该类。所以基本上是强制程序员扩展 HttpServlet 类。
于 2016-02-17T02:31:15.797 回答
-2

基本上我们这里有一个抽象类(HttpServlet),没有任何抽象方法或只有具体方法。我们的 servlet 类javax.servlet.Servlet直接实现(在 RMI 和 CORBA 的情况下)或间接实现(扩展泛型 or HTTPServlet)。

由于接口有 3 个主要方法(和) init(),它们由(抽象类)实现,该类由您的 servlet 类扩展,该类使用这三种方法处理对服务器的浏览器请求。并且根据 HTTP 请求方法的类型,我们的 servlet 类(通过扩展)使用相应的方法,在大多数情况下是或。如果我们将 httpServlet 的所有方法或部分方法作为抽象方法,我们必须实现所有或部分抽象方法,这些方法存在于service()destroy()HttpServletHttpServletdo[xxx]doGetdoPostHttpServlet在我们的 servlet 子类中,但我们只需要实现那些处理 HTTP 方法请求所需的方法。因此,根据我的说法,抽象类中的具体方法根据 HTTP 请求的逻辑提供了实现的自由。

于 2016-01-26T18:18:07.663 回答
-2

基本上 HttpServlet 不包含任何抽象方法,它只是实现抽象的生命周期服务(--,--)方法。它还提供了 7 个 doXXX() 非抽象方法,没有任何与应用程序相关的逻辑来发送 404 错误作为响应。所以HTTPServlet类的扩展类不需要实现doXXX()方法来通知Java开发者HttpServlet类没有完全实现类HttpServlet类做抽象。

于 2018-01-19T03:57:16.700 回答