2012-03-25 17 views
16

Tengo dos interfaces Java y una clase implementadora.Dos interfaces con la misma firma de método implementada en la clase Java

(he utilizado Eclipse para ejecutar el programa directamente, y yo no tratar de comprobar cualquier compilador de advertencia etc. mediante la compilación de forma explícita desde la línea de comandos.)

¿Por qué corren sin problema? ¿Por qué Java lo permite, incluso cuando satisface el "contrato" de ambas interfaces pero crea ambigüedad en la implementación de la clase?

Actualizado el ejemplo.

public interface CassettePlayer { 
    void play(); 
} 

public interface DVDPlayer { 
    void play(); 
} 

public class CarPlayer implements CassettePlayer,DVDPlayer{ 

    @Override 
    public void play() { 
     System.out.println("This plays DVD, screw you Cassette !"); 
    } 

    public static void main(String args[]) { 
     CarPlayer cp = new CarPlayer(); 
     cp.play(); 

     CassettePlayer firstInterface = new CarPlayer(); 
     firstInterface.play(); 

     DVDPlayer secondInterface = new CarPlayer(); 
     secondInterface.play(); 
    } 
} 
+2

¿por qué deberían tener un problema? Esa es la pregunta;) –

+1

Si desea podía tener una clase abstracta con un método 'sayHello' y hacer que' Sample' extendiera la clase abstracta. Tampoco habría ningún problema. – emory

+0

Gracias amigo, tuve la misma pregunta ... – orchidrudra

Respuesta

34

Este escenario permitió específicamente en el Java Language Specification, section 8.1.5:

Está permitido para una sola declaración de método en una clase para poner en práctica los métodos de más de un superinterfaz. Por ejemplo, en el código:

interface Fish { int getNumberOfScales(); } 
interface Piano { int getNumberOfScales(); } 
class Tuna implements Fish, Piano { 
    // You can tune a piano, but can you tuna fish? 
    int getNumberOfScales() { return 91; } 
} 

el método getNumberOfScales en clase Tuna tiene un nombre, firma, y ​​el tipo que coincide con el método declarado en la interfaz Fish y también coincide con el método declarado en la interfaz Piano retorno; se considera implementar ambos.

El texto pasa luego a señalar que si las firmas de los métodos tenían diferentes tipos de retorno, como double y int, no habría manera de implementar ambas interfaces de la misma clase y un error de tiempo de compilación se produciría .

1

no hay conflicto porque ambos especifican el mismo contrato, la implementación de clases sólo proporcionan un método que se llama cuando se hace referencia a través de su interfaz.

1

¿Por qué no? La clase satisface los contratos definidos por ambas interfaces.

1

La clase implementa ambas interfaces, por lo que no hay problema. Por supuesto, este tipo de cosas se deben evitar en escenarios más complejos donde el comportamiento involuntario puede resultar.

5

Para este problema, es necesario entender para qué son las interfaces.

Una interfaz es una especie de "contrato" para que uno sepa qué métodos se implementan obligatoriamente en una clase con esa interfaz.

Si necesita una clase que implemente "DVDPlayer" (porque necesita el método "play()"), encontrará CarPlayer. Lo mismo ocurre con la necesidad de una Clase que implementa CassettePlayer. Esa es la explicación técnica.

Pero, por supuesto, en su codificación semántica debe asegurarse de que el método "play()" de CarPlayer satisfaga la semántica de DVDPlayer y CassettePlayer. Creo que en una aplicación práctica será una mala práctica.

Por supuesto, en su ejemplo, es una mala idea tener dos interfaces que declaren el mismo método. De manera más práctica, debería haber hecho una interfaz "Reproductor" con el método "reproducir()" y tener otras dos interfaces más específicas, DVDPlayer y CassettePlayer (con métodos específicos para DVD y cassettes) que heredan del Reproductor. Por otro lado, si no necesita métodos específicos para DVD o casetes, entonces no necesita dos interfaces diferentes que implementen el mismo método: simplemente use un reproductor de interfaz, eso será suficiente.

1

En esta situación, no hay ningún problema, ya que ambas tienen la misma firma del método. Pero ¿qué pasa con esto?

interface Animal { 
    public void eat() throws IOException; 
} 

interface Plants { 
    public void eat() throws NullPointerException; 
} 

¿Cuál es elegido por el compilador? ¿Por qué aparece el error debajo del código?

public class Test implements Animal, Plants { 

    public void eat() throws IOException { 

    } 
} 

compilador dice: Excepción IOException no es compatible con la cláusula throws en Plants.eat()

Cuestiones relacionadas