可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
HttpServlet
is an abstract class with all implemented methods. Why it is abstract?
The most common answer I got is, to restrict the instantiation of HttpServlet
. But there are other ways of doing it, like a private constructor will restrict the instantiation.
I can understand that they are following Template Method design pattern. If some methods are abstract, user will end up implementing all of them, even if he does not need them for his business logic.
But if HttpServlet
was not abstract, an user can still extend it and override the require methods.
At least by the dictionary meaning of the word 'abstract', its does not make any sense to me to have a abstract class with all implemented method.
Yes a combination of abstract and concrete methods are ok to have.
But if you are making a class abstract why not make those methods abstract which the sub class has to override? or may be do not declare it as abstract at all?
Like doGet()
or doPost()
is this case.
回答1:
To have any useful behaviour, it is expected that you will have to override the methods. HttpServlet does not have useful functionality on its own.
Making its constructors private would limit the ability for subclasses to be created.
The design of HttpServlet was probably not ideal -- as on many pages, forms especially, GET and POST logic should proceed at least partly along a common path. The design idea of HttpServlet however was to offer doGet()
, doPost()
etc implementations answering a 'not supported' error depending on HTTP version. These stubs would be useful to inherit if you needed to return such an answer.
In summary, the API/ interface is complete -- but the functionality is definitively not. Thus it is declared as abstract.
回答2:
HTTPServlet is an abstract class with all implemented methods. Then why it is abstract ?
It is abstract because the implementations of key methods have to be provided by (e.g. overridden by) a custom servlet class. As the javadoc says:
A subclass of HttpServlet must override at least one method, usually one of these:
- doGet, if the servlet supports HTTP GET requests
- doPost, for HTTP POST requests
- doPut, for HTTP PUT requests
- doDelete, for HTTP DELETE requests
- init and destroy, to manage resources that are held for the life of the servlet
- getServletInfo, which the servlet uses to provide information about itself
If you extend the class without overriding any methods, you will get a useless servlet; i.e. one that gives an error response for all requests. Similarly, if the class was not abstract
, then any direct instance of HttpServlet
would be useless.
Hence, the reason for making the HttpServlet
class abstract
is to prevent a (naive) programmer error.
For the record, the reason for providing implementations of all of the methods is to make life simpler for the programmer by providing default behaviour. For instance, if I don't want my servlet to support DELETE requests, the default implementation for doDelete
will conveniently send a response with the "Method not supported" response code.
回答3:
You are forced to extend HttpServlet because you need to add your application specific logic to it. Here is the definition of an abstract class according to oracle's men:
"An abstract class is a class that is declared abstract—it may or may not include abstract methods. Abstract classes cannot be instantiated, but they can be subclassed."
http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
Reason:
We all know that HttpServlet doesnot have any abstract method.
It contains all concrete methods.But still this class is kept abstract.The reason is very simple.
Our own class can act as a Servlet,only when it extends HttpServlet or GenericServlet class,or implements Servlet interface
If HttpServlet class will not be kept abstract,you will not be intrested to extend this class,and your class will not act as Servlet.
ServletContainer uses instanceOf() to know if your class is the child of HttpServlet or GenericServlet or Servlet interface.
Since your class is not the child of HttpServlet,GenericServlet class or implemented Servlet interface,instanceOf() will fail.
回答4:
Basically we have here is an abstract class (HttpServlet
) without any abstract method or only concrete method. Where our servlet class implements javax.servlet.Servlet
directly (in case of RMI and CORBA) or indirectly (extending generic or HTTPServlet
).
As Interface has 3 main methods (init()
, service()
and destroy()
) which is implemented by the HttpServlet
(abstract class) which is extended by your servlet class which process the browser requests made to the server using these three methods. And depending on type of HTTP request method, our servlet class (by extending HttpServlet
) uses the respective do[xxx]
method which is in majority of cases is doGet
or doPost
. If we have all the methods or some of methods of httpServlet as abstract method, we have to implement all or some of the abstract method which are present in HttpServlet
in our servlet subclass but we have to implement only those methods which are required to process the HTTP method request. Thus according to me having concrete method in abstract class provides freedom of implementation depending upon the logic of HTTP request.
回答5:
There are two reason for this.
- First So that you can not create Object of HttpServlet Class. Let suppose it were not protected then we could create obj of this class which would we useless.
- Second There are protected method in HttpServlet class. So to access protected thing of a class in order to have Servlet feature in your implementation class you must extend that class. So basically it is to force programmer to extend HttpServlet Class.
回答6:
Basically HttpServlet does not contains any abstract method, its only implementing life cycle service (--,--) method which is abstract.
And also it is providing 7 doXXX() non abstract methods without having any application related logic to send 404 error as response.
So extended class of HTTPServlet class is no need to implement doXXX() methods
to inform Java developers that HttpServlet class is not fully implemented class HttpServlet class made as abstract.