【问题标题】:Java Interface Contracts IssueJava 接口契约问题
【发布时间】:2014-02-11 15:45:24
【问题描述】:

我有一个名为 I 的界面。该接口由抽象类 AClazz 实现。

AClazz implements I

现在这个抽象类被几个具体类扩展了。

ConcreteClazz extends AClazz
AnotherConcreteClazz extends AClazz

现在当我向接口添加一个新的方法契约时为什么 Eclipse 和 Java 语言会抱怨具体类(ConcreteClazz 中缺少实现>AnotherConcreteClazz)而不是在抽象类 AClazz 中?

如果 AClazz 是一个具体类(而非抽象类)并且从非抽象 AClazz 扩展而来的具体类会再次抱怨具体类中缺少实现吗?

【问题讨论】:

    标签: java inheritance compiler-construction interface abstract-class


    【解决方案1】:

    所以说你的接口I有一个方法m

    public interface I {
         public void m (int someParameter);
    }
    

    现在AClazz 实现了I,并且ConcreteClazz 扩展了AClazz。这意味着ConcreteClazz 也实现了I,无论您在ConcreteClazzclass 声明中是否明确表示。这意味着您可以在任何需要I 的地方使用ConcreteClazz 对象。所以说在某个地方,在其他类中,你有一个方法

    void takeSomeAction(Something x, I y) {
        ....
        y.m (x.getSomeProperty());  // call the interface method
        ....
    }
    

    您可以使用ConcreteClazz 对象调用它:

    ConcreteClazz z = new ConcreteClazz(...);
    Something st;
    
    foo.takeSomeAction(st, z);
    

    你给takeSomeAction 一个ConcreteClazz 用作它的I 参数。然后takeSomeAction 将调用m 方法。除非您在某处为m 提供了实现,否则这将如何工作?

    这就是您需要在AClazzConcreteClazz 中实现m 的原因。您可以AClazz 中实现它,如果这样做是正确的,那么您不需要在ConcreteClazz 中提供另一个实现。但是如果你不在AClazz 中实现它,它不会导致任何错误,因为在运行时,你实际上不能拥有AClazz 类型的对象。但是由于您可以拥有ConcreteClazz 类型的对象,这意味着在某个地方,对于ConcreteClazz,必须有一个m 的实现。

    【讨论】:

    • 是的,谢谢我得到了那部分。现在我很想知道如果 AClazz 是一个具体类而不是抽象类,错误会在哪里引发。 Java 会抱怨在 AClazz 或 ConcreteClazz 中缺少实现吗?
    • @AnupSaumithri 在AClazz。如果AClazz 是一个具体的类,它必须实现I 中的所有方法,否则编译器会显示错误。如果ConcreteClazz 然后扩展AClazz,我不确定如果AClazz 没有编译,编译器是否甚至可以开始编译ConcreteClazz
    【解决方案2】:

    一个Abstract class means, this class contains abstract methods (i.e. no implementation, only definition of method), the classes that are extending it must implement the unimplemented methods

    自从Interface contains 100% pure public abstract methods,其中must be implemented by the classes that are implementing 他们除非它被标记为abstract。再次遵循上述规则。

    【讨论】:

    • 非常感谢。这是一个相当新手的问题,看起来我已经走样了。
    • 反引号用于内联代码块;他们shouldn't be used for emphasis。最好使用星号(斜体)或双星号(粗体)。
    【解决方案3】:

    无论您添加多少新的抽象方法,抽象类仍然是抽象的。因此,当您在 I 接口中添加由抽象类实现的新方法时,编译器不会抱怨。

    一个具体的类不能有任何抽象方法,因为您的子类正在扩展您的抽象类,并且该类没有实现接口新添加的方法,因此编译器会抱怨。因为你所有的子类都继承了新添加的抽象方法,具体类不能有抽象方法。

    【讨论】:

    • 如果这个抽象类是一个具体的类呢?是最后一个子类还是直接实现者内部需要实现?
    • @AnupSaumithri 如果您在父抽象类中添加新接口方法的实现,则无需在子类中执行任何操作。
    • 我想知道如果父抽象类是一个具体类会怎样。 java会在哪里抱怨缺少的实现?在父具体类或子具体类中?谢谢'
    • 父类是抽象的,所以不要抱怨,具体的子类不会被编译。
    猜你喜欢
    • 2023-03-19
    • 1970-01-01
    • 2010-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多