web-dev-qa-db-fra.com

étend la classe et implémente l'interface en java

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

Mais,

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

Pourquoi cas-2 montrant une erreur de compilation { expected. Pourquoi ?? Bien que case-1 s'exécute sans erreur. 

15
Ravi

extends devrait aller avant implements:

class Sub extends Super implements Colorable {}
32
yegor256

J'ai un exemple pour montrer pourquoi étend précède implémente dans la déclaration de classe,

à l'intérieur:

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

classe abstraite: 

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

Classe enfant: 

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.
    }
}

Si vous observez qu'il existe la même méthode getName () à la fois dans l'interface et dans la classe abstraite, celle-ci étant implémentée dans la classe abstraite.

Lorsque vous essayez d'implémenter, il est obligatoire pour une classe de remplacer toutes les méthodes abstraites d'une interface, puis nous essayons d'étendre la classe abstraite qui a déjà une implémentation pour la méthode getName ().

lorsque vous créez une instance d'une classe Child et que vous appelez la méthode getName ()

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

Il y aura un conflit pour qu'un enfant appelle quelle implémentation de méthode, car il y aura deux implémentations pour la même méthode getName ().

Pour éviter ce conflit, ils ont rendu obligatoire l'extension et la mise en oeuvre ultérieure d'une interface.

donc, si une classe abstraite a la même méthode que dans une interface et si la classe abstraite a déjà implémenté la méthode, alors pour une classe enfant, il n'est pas nécessaire de remplacer cette méthode. 

3
ravikumar

Ceci est dû à une spécification dans JLS. Et il y a un certain ordre d'éléments lorsque vous essayez de déclarer une classe en Java:

  • Modificateurs tels que public, private, etc.
  • Le nom de la classe, avec la lettre initiale capitalisée par convention.
  • Le nom du parent de la classe (superclasse), le cas échéant, précédé de Le mot clé extends. Une classe ne peut étendre (sous-classe) qu'un seul parent.
  • Liste d'interfaces implémentées par la classe, séparées par des virgules, si possible, précédées du mot clé implements. Une classe peut implémenter plus d'une interface.
  • Le corps de la classe, entouré d'accolades, { }.

Référence:

http://docs.Oracle.com/javase/tutorial/Java/javaOO/classdecl.html

1
Juvanis

La syntaxe de la définition de classe dans - Page de syntaxe JLS est

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

Je pense que pour simplifier les règles de syntaxe, ils ne l'ont pas rendu interchangeable.

Pour rendre interchangeable, vous avez probablement besoin de quelque chose comme:

NormalClassDeclaration: 
    class Identifier [TypeParameters] [ExtendsImplements] ClassBody

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

Ou même pire, vous pourriez déclarer Extends et Implements pour pouvoir utiliser OR.

J'imagine que ce n'est pas si important que cela vaille la peine d'encombrer les règles d'analyse.

1
Aviram Segal

Il existe une règle en Java si vous souhaitez implémenter une interface et étendre une classe, vous devez d'abord étendre une classe, puis nous implémentons une interface.

interface A{}
class super{}

class sub extends super implements A {}

Lorsque le compilateur Java transforme une classe en bytecode, il doit d'abord rechercher une classe parente. En effet, l'implémentation sous-jacente des classes doit pointer vers le bytecode de la classe parente, qui contient les méthodes et les champs pertinents. Ensuite, il ajoute des pointeurs au code des fonctions de classe enfant - dont certaines sont mandatées par le mot clé 'implements'. 

Comme la classe parent doit être compilable, il est plus facile si le compilateur sait à l’avance ce que cette classe est. De plus, vous ne pouvez étendre qu'une classe mais implémenter un nombre quelconque d'interfaces. Le temps de compilation grimpe si le mot-clé extend peut être mêlé à un nombre quelconque d'instructions implémentations. Les compilateurs veulent échouer aussi vite que possible pour réduire le temps de développement, ce choix est donc logique. De plus, cela vous aide à penser clairement à la classe pour la même raison. 

0
Hemanth Kasireddy

Vous devez faire comme ça. Vous ne pouvez étendre qu'une classe, mais vous pouvez implémenter plusieurs interfaces séparément par virgule. il serait plus convivial pour le lecteur d'avoir d'abord l'extension avant la mise en œuvre

class Sub extends Super implements Colorable
0
Suranga