17

当类抽象中的所有方法都是具体的时,是否有一些实际的编程情况可供某人声明类抽象?

4

9 回答 9

16

好吧,您可以使用模板方法模式,其中有多个覆盖点都具有默认实现,但是组合的默认实现本身是不合法的 - 任何功能实现都必须子类化。

(是的,我不喜欢模板方法模式;))

于 2008-12-12T10:51:04.380 回答
5

抽象类是被声明为抽象的类——它可能包含也可能不包含抽象方法。它们不能被实例化,所以如果你有一个带有具体方法的抽象类,那么它可以被子类化,然后子类可以被实例化。

于 2008-12-12T10:50:03.353 回答
4

想象一个接口,其声明的方法通常在实现时显示相同的默认行为。在编写需要支持接口的类时,您必须一遍又一遍地定义所述默认行为。

为了促进具体类的实现,您可能希望提供一个抽象类,为每个方法提供默认行为。要支持具体类中的接口,您可以从抽象类派生并覆盖偏离标准行为的方法。这样您就可以避免重复实现相同(冗余)的默认行为。

于 2008-12-12T12:43:59.697 回答
2

另一个可能的用例是装饰器,它将所有调用委托给包装的实例。具体的装饰器实现只能覆盖那些添加了功能的方法:

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)。

于 2008-12-12T18:39:56.593 回答
2

以前的答案已经解决了主要问题,但有一个小细节可能值得一提。

您可以拥有一个返回抽象类的(隐藏)子类实例的工厂。抽象类在结果对象上定义契约,并提供默认实现,但该类是抽象的这一事实既使其不能被直接实例化,也表明“真实”实现类的身份不是发表。

于 2008-12-12T23:34:54.440 回答
1

想知道为什么没有人指出 MouseAdapter 的实际示例:

http://docs.oracle.com/javase/6/docs/api/java/awt/event/MouseAdapter.html

用于接收鼠标事件的抽象适配器类。此类中的方法为空。此类的存在是为了方便创建侦听器对象。

于 2013-06-18T10:40:15.583 回答
0

好问题:)

有一件事是肯定的……这当然是可能的。krosenvold 的模板建议是这样做的一个很好的理由。

我只想说一个类不能abstract仅仅为了防止它的实例化而被声明。

这在 Java 语言规范第 8.1.1.1 节中有所提及

于 2008-12-12T10:58:48.860 回答
0

当您有一个重要的类但系统无法为该类创建实例时,因为

  • 这个类是系统很多类的父类;
  • 这对域的需求有很多责任(很多类使用的方法);
  • 此类不代表具体对象;
于 2008-12-12T15:40:13.243 回答
0

小服务程序示例:

所有方法都是具体的,但基类本身是无用的:

删除Author.java

  1. 具有具体 doGet 方法的抽象类。
  2. doGet 调用在受保护字符串 sql_path 中指向的文件。
  3. sql_path 为 null

DeleteAuthor Keep Book.java

  1. 扩展抽象类 DeleteAuthor
  2. 将 sql_path 设置为 delete_author_ KEEP _BOOK.sql

DeleteAuthor烧录书.java

  1. 扩展抽象类 DeleteAuthor
  2. 将 sql_path 设置为 delete_author_ BURN _BOOK.sql
于 2018-08-06T15:15:30.830 回答