web-dev-qa-db-fra.com

Java: extension d'une classe et implémentation d'une interface utilisant la même méthode

Les opérations suivantes ne peuvent probablement pas être effectuées (une erreur de compilation s’affiche: "La méthode héritée A.doSomthing (int) ne peut pas masquer la méthode abstraite publique en B"):

public class A {
    int doSomthing(int x) {
        return x;
    }
}

public interface B {
    int doSomthing(int x);
}

public class C extends A implements B {

    //trying to override doSomthing...

    int doSomthing(int x) {
        return doSomthingElse(x);
    }
}

En supposant que je n’ai le droit de changer ni A ni B, ma question est de savoir si je peux définir C de manière à hériter à la fois de A et de B (supposons qu’il soit nécessaire pour un cadre que C soit à la fois une instance de et B).

Ou sinon, comment travailleriez-vous autour de cela?

Merci!

22
rapt

rendre la méthode publique

public class C extends A implements B {

    //trying to override doSomthing...

    public int myMethod(int x) {
        return doSomthingElse(x);
    }
}

les méthodes d'interface sont toujours public

ou utilisez simplement la composition au lieu de l'héritage

27
ratchet freak

La méthode doSomethis() est package-private en classe A:

public class A {
    int doSomthing(int x) { // this is package-private
        return x;
    }
}

Mais c'est public dans l'interface B:

public interface B {
    int doSomthing(int x); // this here is public by default
}

Le compilateur prend la doSomething() héritée par C de A qui est package-private comme l’implémentation de celle de B qui est public. C'est pourquoi il se plaint -

"La méthode héritée A.doSomthing (int) ne peut pas masquer la méthode abstraite publique en B"

Parce que, bien que override soit une méthode, vous ne pouvez pas limiter le niveau d’accès de la méthode.

La solution est facile, en classe C -

@Override
public int doSomthing(int x) {
    // ...
}
7
Bhesh Gurung

Cela a à voir avec la visibilité. Vous utilisez la visibilité default (sans modificateur) dans C pour myMethod, mais elle doit être public selon l'interface B.

Vous pouvez maintenant penser que vous avez utilisé la visibilité default pour tous, puisque ni dans A, B ni C n’avez-vous sélectionné explicitement l’un des public, private ou protected Cependant, l'interface utilise public que vous l'indiquiez explicitement ou non.

2
Michael McGowan

Il suffit de faire la méthode public pour la remplacer dans C.

0
Costi Ciudatu