为什么HTTPServlet是一个抽象类?任何功能原因?

时间:2013-09-20 05:08:52

标签: java servlets abstract-class private-constructor

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

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

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

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

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

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

但是如果你正在创建一个类抽象,为什么不将那些方法抽象为子类必须覆盖的呢?或者可能根本没有宣布它是抽象的?

就像doGet()doPost()一样。

6 个答案:

答案 0 :(得分:13)

要获得任何有用的行为,您需要覆盖这些方法。 HttpServlet本身没有有用的功能。

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

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

总之, API /接口已经完成 - 但功能绝对不是。因此它被声明为 abstract

答案 1 :(得分:8)

  

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

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

  

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

     
      
  • doGet,如果servlet支持HTTP GET请求
  •   
  • doPost,用于HTTP POST请求
  •   
  • doPut,用于HTTP PUT请求
  •   
  • doDelete,用于HTTP DELETE请求
  •   
  • 初始化和销毁​​,以管理为servlet生命周期而持有的资源
  •   
  • getServletInfo,servlet用来提供有关自身的信息
  •   

如果你扩展类而不覆盖任何方法,你将得到一个无用的servlet;即为所有请求提供错误响应的一个。同样,如果课程不是abstract,那么HttpServlet的任何直接实例都将毫无用处。

因此,制作HttpServletabstract的原因是为了防止(天真)程序员错误。


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

答案 2 :(得分:1)

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

"抽象类是一个被声明为abstract的类 - 它可能包含也可能不包含抽象方法。抽象类不能被实例化,但它们可以被子类化。"

<强> 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()将失败。

答案 3 :(得分:-2)

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

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

答案 4 :(得分:-2)

这有两个原因。

  1. 首先,你不能创建HttpServlet类的Object。假设它没有受到保护,那么我们可以创建这个类的obj,这将是我们无用的。
  2. Second HttpServlet类中有protected方法。因此,要访问类的受保护的东西以便在您的实现类中具有Servlet功能,您必须扩展该类。所以基本上是强制程序员扩展HttpServlet Class。

答案 5 :(得分:-2)

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