接口没有看到具体的实现

时间:2015-01-30 22:41:12

标签: java

我有

ISomeInterface

public interface ISomeInterface{
    public void myMethod();
} 

AbstractClass

public abstract class AbstractClass implements ISomeInterface{

    public void myMethod(){
    //...here goes implemetations
    }
}

ConcreteClass

public class ConcreteClass extends AbstractClass {
    //...
}

编译器打印比ConcreteClass不是抽象的,并且不会覆盖myMethod中的抽象方法ISomeInterface

这个想法是给一个抽象类提供实现,然后在扩展它的类中继承它。 我认为ConcreteClass应该从AbstractClass获得实现,因为它正在扩展它。对?怎么了?

更新

直到现在我还没有注意到method是错误的,而且必须是myMethod。无论如何,同样的错误。

UPDATE2

问题是在AbstractClass中,他们的方法名称正确但签名不正确。根据界面更改后,问题解决了:)

5 个答案:

答案 0 :(得分:2)

AbstractClass中,您正在创建方法myMethod(),但您的接口方法method()未在ConcreteClass中实施。名字不同。

答案 1 :(得分:2)

假设您的示例代码已完成,您需要在界面中实现method。在AbstractClass中,您已将其称为myMethod

您可以在任何覆盖方法上使用@Override注释。这将告诉您是否使用了错误的参数类型,方法名称或不兼容的返回类型(参数和返回类型不必相同;例如,它们可以是covariant

此外,在Java中,我们不倾向于使用I为接口名称添加前缀(与C#中的约定不同)。您的界面通常称为SomeInterface,而不是ISomeInterface

此外,public接口is implicit上的方法,因此您可以将其保留。如果你确实包括它,你应该包括abstract以包含所有隐式修饰符。

更新的代码示例如下:

public interface SomeInterface{
  void method();
} 

public abstract class AbstractClass implements SomeInterface {
  @Override
  public void method(){
      //...here goes implemetations
  }
}

答案 2 :(得分:0)

可能会覆盖错误的方法。发生的事情是您可能尝试覆盖抽象类中的方法,但实际上您要做的是仅使用新名称定义新方法。在接口中,该方法名为method,但在您的抽象类中,您的方法名为myMethod

所以,看看这个:

public abstract class AbstractClass implements ISomeInterface{

    // Not the same name as in the interface
    public void myMethod(){
        //...here goes implemetations
    }
}

要解决此问题,只需将子类中的方法名称更改为正确的名称。

public abstract class AbstractClass implements ISomeInterface{
    // Now you have the correct name and inheritance will
    // work as expected
    @Override
    public void method(){
        //...here goes implemetations
    }
}

这也是解释@Override注释的完美案例;)

  
    

覆盖方法时,您可能希望使用@Override注释来指示编译器您要覆盖超类中的方法。如果由于某种原因,编译器检测到该方法在其中一个超类中不存在,那么它将生成错误。

  

当您使用注释@Override声明方法时,重写的方法必须匹配interface-method(或超类方法)的签名。详细了解@Override in the Oracle Docs

而且,如果您没有尝试覆盖抽象类中名为method的方法,则只需将该方法添加到具体类中,如下所示:

public class ConcreteClass extends AbstractClass {
    // Now we are implementing the correct method from the interface
    // If not, there will be a compiler error.
    @Override
    public void method() {

    }
    //...
}

在可能相关的旁注上:方法可以具有相同名称但具有不同的参数列表。这称为重载(或重载方法),您可以在this article中详细了解。

编辑:由于OP使用Java 5 this question可能很有趣。在Java 5和Java 6之间更改了@Override注释。在Java 5中,当从接口实现方法时,不允许使用@Override注释,只允许从超类中重写方法时。

答案 3 :(得分:0)

您的界面定义

public void method();

但你的抽象类有

public void myMethod(){
    //...here goes implemetations
}

哪个不一样!添加Override注释以在编译时捕获此类问题。

@Override
public void myMethod(){ // <-- compile error.
    //...here goes implemetations
}

来自链接的Javadoc,

  

表示方法声明旨在覆盖超类型中的方法声明。

答案 4 :(得分:0)

我注意到的第一件事是你的方法在接口和抽象类中没有被命名为相同的东西。