2009-05-18 3 views
7

in "The Java ™ linguaggio di programmazione, quarta edizione" di Ken Arnold, James Gosling, David Holmes, il suo detto che:Java Interfaccia: Ereditare, di primaria importanza, e metodi Overloading

paragrafo: (4.3.2) "Analogamente, se un'interfaccia eredita più di un metodo con la stessa firma, o se una classe implementa interfacce diverse contenenti un metodo con la stessa firma, esiste solo un tale metodo. L'implementazione di questo metodo viene definita in ultima analisi la classe che implementa le interfacce e non vi è alcuna ambiguità. Se i metodi hanno la stessa firma ma tipi di ritorno diversi, uno dei tipi restituiti deve essere un sottotipo di tutti gli altri, altrimenti un si verifica un errore in fase di compilazione. L'implementazione deve definire un metodo che restituisce quel sottotipo comune ".

Qualcuno mi può dare qualche esempio di codice che giustifica i punti di cui al punto di cui sopra?

Ho provato a scrivere il codice e provare ciò che viene menzionato ma io sono sempre a tempo di compilazione errore il sub-interfaccia nasconde il metodo di interfaccia di base così può implementare solo metodo di sub-interfaccia.

Grazie in anticipo. -Arun

+0

si può mostrare il codice? –

+1

pubblica il tuo codice e gli errori del compilatore amico ... almeno dacci qualcosa per (a) riprodurre il problema; e (b) andare da lì. – corlettk

+0

Tutti mi dispiace davvero, stavo provando a testare ciò che è stato menzionato nel para sopra menzionato usando j2sdk1.4.2_08 - Non mi ero accorto che il libro è stato scritto per JDK1.5 Ciò significa che se si compila lo snippet di codice di "Daniel Schneller" utilizzando JDK1.4 si otterrà un "ImplementationOfAandB.java:17: methodB() in ImplementationOfAandB non può implementare il metodoB() in InterfaceA; tentare di utilizzare il tipo di ritorno incompatibile" errore di compilazione mentre con JDK1.5 viene eseguito solo bene. – akjain

risposta

2

Nelle due interfacce seguenti methodA() è identicamente definito in termini di parametri (nessuno) e tipo di ritorno (int). La classe di implementazione in basso definisce un singolo metodo con questa firma esatta. Poiché è conforme a entrambe le interfacce, non si verificano problemi in questo caso: tutte le chiamate effettuate tramite un riferimento di tipo InterfaceA o InterfaceB verranno inviate a questa implementazione.

Il secondo methodB() è definito come restituire qualsiasi sottotipo di Number (o Number stesso) in InterfaceA. InterfaceB definisce methodB() come restituisce un Integer che è un sottotipo di Number. La classe di implementazione implementa effettivamente il metodo con Integer, in conformità al contratto di entrambi InterfaceA e InterfaceB. Nessun problema qui neanche. Il caso commentato di methodB() implementato come restituisce un Double tuttavia non funzionerebbe: mentre avrebbe soddisfatto il contratto di InterfaceA, sarebbe in conflitto con InterfaceB (che richiede un Integer).

Se InterfaceA e InterfaceB stati precisando altresì contratti (diversi) per un methodC() (commentata nell'esempio) questo sarebbe contraddittorio e creare un errore di compilazione. L'implementazione di entrambe le firme (diversa solo nel tipo restituito) non è consentita in Java.

Le regole precedenti valgono anche se si aggiungono parametri ai metodi. Per semplicità ho tenuto questo fuori dall'esempio.

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

Tutti mi dispiace davvero - stavo cercando di testare ciò che è stato menzionato nel para sopra menzionato usando j2sdk1.4.2_08 - Non avevo capito che il il libro è scritto per JDK1.5 Quindi ciò significa che se si compila il frammento di codice di "Daniel Schneller" usando JDK1.4 si otterrà un "ImplementationOfAandB.java:17: methodB() in ImplementationOfAandB non può implementare methodB() in InterfaceA; tentativo di utilizzare il tipo di errore "tipo di ritorno incompatibile" mentre con JDK1.5 funziona correttamente. – 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() { } 
} 

Come si può vedere, Impl.method() implementa sia A.method() e B.method(), mentre Impl.returnMethod() restituisce un B, che è un figlio di Object, adempiendo così anche A.returnMethod() s' contratto. Quest'ultimo richiederebbe un tipo di reso che non sia un genitore del tipo di ritorno di B.returnMethod() che sarebbe un errore comile, dal momento che nessuna implementazione di questo tipo potrebbe esistere in .

+0

Ma Impl deve implementare l'oggetto ReturnMethod(), giusto? –

+0

È C#? La domanda riguarda Java. –

+0

Non credo che sia importante quale lingua;) –

1

'questo che vuoi dire ?:

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

Tale metodo MyClass viene generato automaticamente da javac come metodo ponte sintetico. È necessario implementare un metodo singolo restituendo un tipo compatibile con tutti i metodi implementati/sovrascritti (in questo 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

Le risposte condensate sono più facili da leggere – davids