2009-05-18 10 views
7

En "el lenguaje de programación Java ™, cuarta edición" Por Ken Arnold, James Gosling, David Holmes, su mencionado que:Java Interfaz: Herencia de primer orden, y, Métodos Sobrecarga

párrafo: (4.3.2) "De manera similar, si una interfaz hereda más de un método con la misma firma, o si una clase implementa interfaces diferentes que contienen un método con la misma firma, solo hay un método de este tipo. La implementación de este método está definida en última instancia por la clase que implementa las interfaces, y no hay ambigüedad allí. Si los métodos tienen la misma firma pero diferentes tipos de devolución, entonces uno de los tipos de devolución debe ser un subtipo de todos los demás, de lo contrario un error en tiempo de compilación. La aplicación debe definir un método que devuelve ese subtipo común ".

¿Alguien puede dar un código de ejemplo que justifica los puntos del párrafo anterior?

Traté de escribir el código y probar lo que se menciona pero yo estoy recibiendo en tiempo de compilación de error la sub-interfaz oculta el método de interfaz de base de manera que sólo puede implementar el método sub-interfaz.

Gracias de antemano. -Arun

+0

¿Puede mostrar el código? –

+1

publica tu código y tus errores de compilación tipo ... al menos danos algo para (a) reproducir el problema; y (b) ir desde allí. – corlettk

+0

Todo el mundo lo siento mucho. Estaba intentando probar lo que se mencionó en el párrafo mencionado anteriormente usando j2sdk1.4.2_08. No me di cuenta de que el libro está escrito para JDK1.5 Eso significa que si compila el fragmento de código por "Daniel Schneller" usando JDK1.4 obtendrás un "ImplementationOfAandB.java:17: methodB() en ImplementationOfAandB no puede implementar methodB() en InterfaceA; intentando usar el tipo de retorno incompatible" error de compilación mientras que con JDK1.5 solo ejecuta multa. – akjain

Respuesta

2

En las siguientes dos interfaces methodA() se define de forma idéntica en términos de parámetros (ninguno) y tipo de retorno (int). La clase de implementación en la parte inferior define un único método con esta firma exacta. Como cumple con ambas interfaces, no hay problema: todas las llamadas realizadas a través de una referencia de tipo InterfaceA o InterfaceB se enviarán a esta implementación.

El segundo methodB() se define como devolver cualquier subtipo de Number (o Number sí mismo) en InterfaceA. InterfaceB define methodB() como devolver un Integer que es un subtipo de Number. La clase de implementación realmente implementa el método con Integer, cumpliendo así con el contrato de ambos InterfaceA y InterfaceB. No hay problema aquí tampoco. El caso comentado de methodB() que se implementa como devolver Double sin embargo no funcionaría: Si bien cumpliría el contrato de InterfaceA, entraría en conflicto con InterfaceB (que exige un Integer).

Si InterfaceA y InterfaceB también fueron especificando (diferentes) contratos para un methodC() (comentado en el ejemplo) esto sería contradictorio y crear un error de compilación. La implementación de ambas firmas (que difieren solo en el tipo de devolución) no está permitida en Java.

Las reglas anteriores también se aplicarán si se agregan parámetros a los métodos. Por simplicidad, mantuve esto fuera del ejemplo.

public interface InterfaceA { 
    public int methodA(); 
    public Number methodB(); 
    // public int methodC(); // conflicting return type 
} 

public interface InterfaceB { 
    public int methodA(); 
    public Integer methodB(); 
    // public String methodC(); // conflicting return type 
} 

public class ImplementationOfAandB implements InterfaceA, InterfaceB { 
    public int methodA() { 
     return 0; 
    } 
    public Integer methodB() { 
     return null; 
    } 
    // This would NOT work: 
    // public Double methodB() { 
    //  return null; 
    // } 
} 
+0

Todo el mundo lo siento mucho - Estaba tratando de probar lo que se menciona en el párrafo antes mencionado usando j2sdk1.4.2_08 - No me di cuenta de que el book está escrito para JDK1.5 Eso significa que si compila el fragmento de código de "Daniel Schneller" usando JDK1.4 obtendrá "ImplementationOfAandB.java:17: methodB() en ImplementationOfAandB no puede implementar methodB() en InterfaceA; intentando usar un "error de compilación de tipo de retorno incompatible" mientras que con JDK1.5 simplemente funciona bien. – akjain

1
interface A 
{ 
    void foo(); 
    //int bar(); <-- conflicts with B.bar() because of different return type 
} 

interface B 
{ 
    void foo(); 
    //double bar(); <-- conflicts with A.bar() because of different return type 
} 

class C implements A, B 
{ 
    void foo() // this implements A.foo() AND B.foo() 
    { 
     ... 
    } 
} 
8
interface A { 
    void method(); 
    Object returnMethod(); 
} 
interface B { 
    void method(); 
    B returnMethod(); 
} 

class Impl implements A,B 
{ 
    void method() { } 
    B returnMethod() { } 
} 

Como se puede ver, Impl.method() implementos tanto A.method() y B.method(), mientras Impl.returnMethod() devuelve un B, que es un hijo de Object, cumpliendo así A.returnMethod() 's contrato también. ¿Esta última requeriría un tipo de devolución que no sea uno de los padres del tipo de devolución B.returnMethod() que sería un error de comile, ya que tal implementación no podría existir en Impl.

+0

Pero Impl tiene que implementar el objeto ReturnMethod(), ¿verdad? –

+0

¿Eso es C#? La pregunta es sobre Java. –

+0

No creo que importe el idioma;) –

1

Es esto lo que quiso decir ?:

interface A { 
    Object get(); 
} 
interface B { 
    Number get(); 
} 

abstract class MyClass implements A, B { 
    // Try to override A.get, but cause a compile error. 
    public Object get() { return null; } 
} 

un procedimiento de este tipo en miclase generado automáticamente por javac como método puente sintético. Debe implementar un único método que devuelva un tipo compatible con todos los métodos implementados/reemplazados (en este caso, Number/Integer/Double/etc).

1
/** 
* This is what you have 
*/ 
interface IXR { 
     //bla-bla-bla 
} 

class CXR implements IXR { 
     //concrete implementation of bla-bla-bla 
} 

interface IX { 
     public IXR f(); 
} 

interface IYR { 
     //some other bla-bla-bla 
} 

class CYR implements IYR { 
     //concrete implementation of the some other bla-bla-bla 
} 

interface IY { 
     public IYR f(); 
} 






/** 
* This is what you need to add 
*/ 
interface IZR extends IXR, IYR { 
     //EMPTY INTERFACE 
} 

class CZXR extends CXR implements IZR { 
     //EMPTY CLASS 
} 

class CZYR extends CYR implements IZR { 
     //EMPTY CLASS 
} 

class CZ implements IX, IY 
{ 
     public static boolean someCondition = true; 

     public IXR implementationOf_X_f() 
     { 
       System.out.println("CXR"); 
       return new CZXR(); 
     } 

     public IYR implementationOf_Y_f() 
     { 
       System.out.println("CYR"); 
       return new CZYR(); 
     } 

     public IZR f() { 
       if (someCondition) { 
         return (IZR) implementationOf_X_f(); 
       } else { 
         return (IZR) implementationOf_Y_f(); 
       } 
     } 

} 






/** 
* This is the usage of the required class 
*/ 
class program 
{ 
     public static void main(String[] x) { 
       CZ o = new CZ(); 
       IZR r = o.f(); 
       if (CZ.someCondition) { 
         CXR xr = (CXR) r; 
         //bla-bla-bla 
       } else { 
         CYR yr = (CYR) r; 
         //bla-bla-bla 
       } 
     } 
} /** 
* This is what you have 
*/ 
interface IXR { 
     //bla-bla-bla 
} 

class CXR implements IXR { 
     //concrete implementation of bla-bla-bla 
} 

interface IX { 
     public IXR f(); 
} 

interface IYR { 
     //some other bla-bla-bla 
} 

class CYR implements IYR { 
     //concrete implementation of the some other bla-bla-bla 
} 

interface IY { 
     public IYR f(); 
} 






/** 
* This is what you need to add 
*/ 
interface IZR extends IXR, IYR { 
     //EMPTY INTERFACE 
} 

class CZXR extends CXR implements IZR { 
     //EMPTY CLASS 
} 

class CZYR extends CYR implements IZR { 
     //EMPTY CLASS 
} 

class CZ implements IX, IY 
{ 
     public static boolean someCondition = true; 

     public IXR implementationOf_X_f() 
     { 
       System.out.println("CXR"); 
       return new CZXR(); 
     } 

     public IYR implementationOf_Y_f() 
     { 
       System.out.println("CYR"); 
       return new CZYR(); 
     } 

     public IZR f() { 
       if (someCondition) { 
         return (IZR) implementationOf_X_f(); 
       } else { 
         return (IZR) implementationOf_Y_f(); 
       } 
     } 

} 






/** 
* This is the usage of the required class 
*/ 
class program 
{ 
     public static void main(String[] x) { 
       CZ o = new CZ(); 
       IZR r = o.f(); 
       if (CZ.someCondition) { 
         CXR xr = (CXR) r; 
         //bla-bla-bla 
       } else { 
         CYR yr = (CYR) r; 
         //bla-bla-bla 
       } 
     } 
} 
+0

Las respuestas condensadas son más fáciles de leer – davids