Are there some practical programming situations for someone to declare a class abstract when all the methods in it are concrete?
问题:
回答1:
Well you could be using a template method pattern where there are multiple override points that all have default implementations but where the combined default implementations by themselves are not legal - any functional implementation must subclass.
(And yes, I dislike the template method pattern ;))
回答2:
An abstract class is a class that is declared abstract - it may or may not include abstract methods. They cannot be instantiated so if you have an abstract class with concrete methods then it can be subclassed and the subclass can then be instantiated.
回答3:
Immagine an interface whose declared methods usually show the same default behavior when implemented. When writing a class that needs to support the interface you have to define said default behavior over and over.
To facilitate implementation of your concrete classes you might want to provide an abstract class providing default behavior for each method. To support the interface in a concrete class you can derive from the abstract class and override methods if they deviate from the standard behavior. That way you'll avoid the repeated implementation of the same (redundant) default behavior.
回答4:
Another possible use case is a decorator which delegates all calls to the wrapped instance. A concrete decorator implementation can override only those methods where functionality is added:
public interface Foo {
public void bar();
}
public abstract class FooDecorator implements Foo {
private final Foo wrapped;
public FooDecorator(Foo wrapped) { this.wrapped = wrapped; }
public void bar() { wrapped.bar(); }
}
public class TracingFoo extends FooDecorator {
//Omitting constructor code...
public void bar() {
log("Entering bar()");
super.bar();
log("Exiting bar()");
}
}
Although I don't really see the necessarity to declare FooDecorator as abstract (non-abstract example: HttpServletRequestWrapper).
回答5:
Previous answers already hit the main issues, but there's a minor detail that might be worth mentioning.
You could have a factory that returns instances of (hidden) subclasses of the abstract class. The abstract class defines the contract on the resulting object, as well as providing default implementations, but the fact that the class is abstract both keeps it from being instantiated directly and also signals the fact that the identity of the "real" implementation class is not published.
回答6:
Wondering why no one has pointed to the Practical Example of MouseAdapter:
http://docs.oracle.com/javase/6/docs/api/java/awt/event/MouseAdapter.html
An abstract adapter class for receiving mouse events. The methods in this class are empty. This class exists as convenience for creating listener objects.
回答7:
Nice question :)
One thing is for sure ... this is certainly possible. The template suggestion by krosenvold is one good reason for doing this.
I just want to say that a class must not be declared abstract
just for preventing it's instantiation.
This is referred in the Java Language Specification Section 8.1.1.1
回答8:
When you have an important class but the system cannot create an instance fo this class, because
- this class is parent of a lot of classes of the system;
- this has a lot of responsability (methods used by a lot of class) for domain's requires;
- this class not represents a concrete object;
回答9:
Servlet Example:
All methods are concrete, but the base class is useless by itself:
DeleteAuthor.java
- Abstract class with concrete doGet method.
- doGet calls file pointed to in protected string sql_path.
- sql_path is null.
DeleteAuthorKeepBook.java
- extends abstract class DeleteAuthor
- sets sql_path to delete_author_KEEP_BOOK.sql
DeleteAuthorBurnBook.java
- extends abstract class DeleteAuthor
- sets sql_path to delete_author_BURN_BOOK.sql