36
interface Bouncable{ } 
interface Colorable extends Bouncable{ } 
class Super implements Colorable{ } 
class Sub extends Super implements Colorable {} // Ok (case -1)

但,

class Sub implements Colorable extends Super {} // error (case -2)

为什么case-2显示编译错误{ expected。为什么 ??虽然,case-1执行没有错误。

4

6 回答 6

64

extends应该先去implements

class Sub extends Super implements Colorable {}
于 2012-12-24T13:07:17.100 回答
8

我有一个例子来说明为什么在类声明中extends先于implements,

界面:

public interface IParent {
    void getName();
    void getAddress();
    void getMobileNumber();
}

抽象类:

public abstract class Parent {
    public abstract void getAge();
    public void getName(){
        System.out.print("the parent name");
    }
}

儿童班:

public class Child extends Parent implements IParent {

    @Override
    public void getAddress() {
       System.out.print(" Child class overrides the Parent class getAddress()");
    }

    @Override
    public void getMobileNumber() {
        System.out.print(" Child class overrides the Parent class getMobileNumber()");
    }

    @Override
    public void getAge() {
        //To change body of implemented methods use File | Settings | File Templates.
    }
}

如果您观察到接口和抽象类中都有相同的方法 getName(),那么在抽象类中该方法具有实现。

当您尝试实现时,类必须重写接口的所有抽象方法,然后我们尝试扩展已经具有方法 getName() 实现的抽象类。

当您创建 Child 类的实例并将方法 getName() 称为

Child child = new Child();
child.getName();

孩子调用哪个方法实现会有冲突,因为同一个方法 getName() 会有两个实现。

为了避免这种冲突,他们强制先扩展并稍后实现接口。

因此,如果抽象类具有与接口中相同的方法,并且如果抽象类已经实现了该方法,那么对于子类,则无需重写该方法

于 2014-04-30T10:38:53.507 回答
4

java中有一个规则,如果要实现一个接口并扩展一个类,我们必须先扩展一个类,然后再实现一个接口

interface A{}
class super{}

class sub extends super implements A {}

当 Java 编译器将类转换为字节码时,它必须首先查找父类。那是因为类的底层实现是指向父类的字节码——它包含相关的方法和字段。然后它添加指向子类函数代码的指针——其中一些是由'implements'关键字强制执行的。

因为父类必须是可编译的,所以如果编译器预先知道该类是什么会更容易。此外,您只能扩展一个类,但可以实现任意数量的接口。如果可以在任意数量的实现指令中混合使用 extends 关键字,则编译时间会增加。编译器希望尽快失败以减少开发时间,因此这种选择是合乎逻辑的。此外,出于同样的原因,它可以帮助您清楚地思考课程。

于 2017-07-13T15:43:17.877 回答
1

这是因为JLS中的规范。当您尝试在 Java 中声明一个类时,元素的顺序是一定的:

  • 修饰符,例如public,private等。
  • 类名,首字母按约定大写。
  • 类的父类(超类)的名称(如果有),前面带有关键字extends。一个类只能扩展(子类)一个父类。
  • 由类实现的接口的逗号分隔列表(如果有),前面带有关键字implements。一个类可以实现多个接口。
  • 类主体,被大括号包围,{ }.

参考:

http://docs.oracle.com/javase/tutorial/java/javaOO/classdecl.html

于 2012-12-24T13:13:27.800 回答
1

JLS Syntax Page的类定义语法是

NormalClassDeclaration: 
    class Identifier [TypeParameters] [extends Type] [implements TypeList] ClassBody

我认为为了简化语法规则,他们并没有使其可互换。

为了使可互换,您可能需要类似的东西:

NormalClassDeclaration: 
    class Identifier [TypeParameters] [ExtendsImplements] ClassBody

ExtendsImplements:
    [extends Type] [implements TypeList] | [implements TypeList] [extends Type]

或者更糟糕的是,您可能需要声明ExtendsImplements使用OR.

我想把解析规则弄得乱七八糟并不重要。

于 2012-12-24T13:20:18.937 回答
0

你必须这样做。您只能扩展一个类,但可以通过逗号分别实现多个接口。在实施之前先进行扩展会更便于读者阅读

class Sub extends Super implements Colorable
于 2012-12-24T13:19:27.833 回答