当类抽象中的所有方法都是具体的时,是否有一些实际的编程情况可供某人声明类抽象?
9 回答
好吧,您可以使用模板方法模式,其中有多个覆盖点都具有默认实现,但是组合的默认实现本身是不合法的 - 任何功能实现都必须子类化。
(是的,我不喜欢模板方法模式;))
抽象类是被声明为抽象的类——它可能包含也可能不包含抽象方法。它们不能被实例化,所以如果你有一个带有具体方法的抽象类,那么它可以被子类化,然后子类可以被实例化。
想象一个接口,其声明的方法通常在实现时显示相同的默认行为。在编写需要支持接口的类时,您必须一遍又一遍地定义所述默认行为。
为了促进具体类的实现,您可能希望提供一个抽象类,为每个方法提供默认行为。要支持具体类中的接口,您可以从抽象类派生并覆盖偏离标准行为的方法。这样您就可以避免重复实现相同(冗余)的默认行为。
另一个可能的用例是装饰器,它将所有调用委托给包装的实例。具体的装饰器实现只能覆盖那些添加了功能的方法:
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()");
}
}
虽然我并不认为有必要将 FooDecorator 声明为抽象(非抽象示例:HttpServletRequestWrapper)。
以前的答案已经解决了主要问题,但有一个小细节可能值得一提。
您可以拥有一个返回抽象类的(隐藏)子类实例的工厂。抽象类在结果对象上定义契约,并提供默认实现,但该类是抽象的这一事实既使其不能被直接实例化,也表明“真实”实现类的身份不是发表。
想知道为什么没有人指出 MouseAdapter 的实际示例:
http://docs.oracle.com/javase/6/docs/api/java/awt/event/MouseAdapter.html
用于接收鼠标事件的抽象适配器类。此类中的方法为空。此类的存在是为了方便创建侦听器对象。
好问题:)
有一件事是肯定的……这当然是可能的。krosenvold 的模板建议是这样做的一个很好的理由。
我只想说一个类不能abstract
仅仅为了防止它的实例化而被声明。
当您有一个重要的类但系统无法为该类创建实例时,因为
- 这个类是系统很多类的父类;
- 这对域的需求有很多责任(很多类使用的方法);
- 此类不代表具体对象;
小服务程序示例:
所有方法都是具体的,但基类本身是无用的:
删除Author.java
- 具有具体 doGet 方法的抽象类。
- doGet 调用在受保护字符串 sql_path 中指向的文件。
- sql_path 为 null。
DeleteAuthor Keep Book.java
- 扩展抽象类 DeleteAuthor
- 将 sql_path 设置为 delete_author_ KEEP _BOOK.sql
DeleteAuthor烧录书.java
- 扩展抽象类 DeleteAuthor
- 将 sql_path 设置为 delete_author_ BURN _BOOK.sql