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:
1. doGet, if the servlet supports HTTP GET requests
2. doPost, for HTTP POST requests
3. doPut, for HTTP PUT requests
4. doDelete, for HTTP DELETE requests
5. init and destroy, to manage resources that are held for the life of the servlet
6. 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.