扩展类并在java中实现接口

时间:2012-12-24 13:06:34

标签: java oop extends implements

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 执行时没有错误。

6 个答案:

答案 0 :(得分:33)

extends应该在implements之前:

class Sub extends Super implements Colorable {}

答案 1 :(得分:4)

我有一个例子来说明为什么extends在类声明中的实现之前,

inerface:

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()会有两个实现。

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

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

答案 2 :(得分:1)

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

  • publicprivate等修饰符
  • 班级名称,首字母按大会大写。
  • 类的父级(超类)的名称(如果有),前面带有 关键字extends。一个类只能扩展(子类)一个 父节点。
  • 由类实现的以逗号分隔的接口列表if any,前面有关键字implements。一个班可以实现 多个界面。
  • 被括号{ }包围的班级团体。

参考:

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

答案 3 :(得分: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

我认为值得混淆解析规则并不重要。

答案 4 :(得分:0)

你必须这样做。您只能扩展一个类,但可以单独用逗号实现多个接口。在工具

之前首先进行扩展会更方便读者阅读
class Sub extends Super implements Colorable

答案 5 :(得分:0)

如果想要实现一个接口并扩展一个类,我们必须首先扩展一个类然后实现一个接口

interface A{}
class super{}

class sub extends super implements A {}

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

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