7

我有一个接口 A,我必须为此提供几个不同的实现。但是,这些实现共享一些辅助方法,因此我将这些方法移至抽象基类。

Interface A {
    void doX();
}

abstract Class B implements A {
    protected void commonY() {
        // ...
    }

    @Override
    public abstract void doX();
}

Class C extends B {
    @Override
    public void doX() {
        // ...
    }
}

Class D extends B {
    @Override
    public void doX() {
        // ...
    }
}

我的代码按预期工作,但我有几个问题:

  • 我应该在 B 类中声明抽象方法 doX() 吗?为什么不)?

  • 我是否还应该在 C 类和 D 类上明确声明“实现 A”?为什么不)?

4

6 回答 6

8

我认为最好按以下方式进行:

Interface A {
        void doX();
}

abstract Class B {
        protected void commonY() {
                // ...
        }
}

Class C extends B implements A{

        public void doX() {
                // ...
        }
}

Class D extends B implements A{

        public void doX() {
                // ...
        }
}

您不应该将接口(方法的签名)与实现混合。

于 2008-12-09T11:47:21.883 回答
4
  • 我应该在 B 类中声明抽象方法 doX() 吗?为什么不)?

不,它是一个抽象类——定义接口意味着所有子类都需要实现这些方法。换句话说,它是多余的。

  • 我是否还应该在 C 类和 D 类上明确声明“实现 A”?为什么不)?

不,再次 - 因为您的超类(抽象基类)实现了该接口,所以您的具体子类将保证实现该接口。

于 2008-12-09T11:44:55.630 回答
1

我只会抛出另一个选项。

将抽象类 B 转换为不实现 A 的 AUtil 类。方法签名可能需要使用类型为 A 的附加参数。

C 和 D 实现 A,并在内部实例化一个 AUtil。这确实允许 C 和 D 扩展其他类。

于 2008-12-09T12:00:04.167 回答
1

我同意 JeeBee:考虑在抽象基类以外的地方实现您的辅助方法。

如果您的辅助方法 commonY() 仅存在于抽象基类 B 中,则所有实现接口 A 的类都必须扩展基类 B 才能利用 commonY() 的实现。但是,您可能并不总是希望被迫扩展 B 类。

另外,如果你以后想改变 commonY() 的实现怎么办?然后,您将影响接口 A 的许多实现。但是,如果您不控制接口 A 的所有这些实现,您可能会无意中影响它们的功能(以一种不好的方式)。

在这种情况下使用抽象基类可能只会带走一些灵活性,而不会给您任何回报。

于 2008-12-09T22:04:07.597 回答
0

实现接口的抽象类必须实现该接口。具体来说,它必须为该接口中指定的每个方法名称和签名具有公共方法。

继承是传递的。如果类 C 派生实现接口 A 的类 B,则无需编写类 C 实现接口 A。但是,它也没有太大的危害。

于 2008-12-09T11:45:03.917 回答
0

我不会声明doX()B也不会添加“ implements ACD因为你不应该重复自己

doX()中的摘要B没有添加任何内容,因为它已经由“ implements A”指定。将“ implements A”添加到Cand也是如此D

这些子句的唯一可能用途是文档:如果您想非常明确地表示C(or D) is-a A,那么您可以添加implements,但您应该知道这对编译器来说并不重要。

于 2008-12-09T11:46:02.760 回答