在实现具有抽象类的接口时声明什么(不)?

时间:2008-12-09 11:40:41

标签: java class interface declaration abstract

我有一个接口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”?为什么(不是)?

6 个答案:

答案 0 :(得分: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() {
                // ...
        }
}

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

答案 1 :(得分:4)

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

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

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

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

答案 2 :(得分:1)

我会抛出另一个选项。

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

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

答案 3 :(得分:1)

我同意JeeBee:考虑在除抽象基类之外的某个地方实现辅助方法。

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

此外,如果您希望将来更改commonY()的实现,该怎么办?然后,您将影响接口A的许多实现。但是,如果您不控制接口A的所有这些实现,则可能会影响它们的功能(以一种糟糕的方式)而不打算这样做。

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

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

我不会在doX()中声明B,也不会在implements AC上添加“D”,因为您应该not repeat yourself。< / p>

doX()中的摘要B不会增加任何内容,因为它已由“implements A”指定。将“implements A”添加到CD也是如此。

这些条款唯一可能的用途是文档:如果你想明确C(或D)是一个A,那么你可以添加implements,但你应该知道它对编译器来说无关紧要。