2012-04-13 17 views
6

Il seguente codice utilizza il concetto di metodo che esegue l'override in Java.Tipo di ritorno covariant in Java

package pkg; 

import java.util.ArrayList; 
import java.util.List; 

abstract class SuperClass 
{ 
    abstract public List<String>getList(); 
} 

final class SubClass extends SuperClass 
{ 
    private List<String>list=null; 

    @Override 
    public ArrayList<String> getList() 
    { 
     list=new ArrayList<String>(); 
     list.add("A"); 
     list.add("B"); 
     return (ArrayList<String>) list; 
    } 
} 

final public class Main 
{ 
    public static void main(String[] args) 
    { 
     SuperClass s=new SubClass(); 
     List<String>list=s.getList(); 

     for(String str:list) 
     { 
      System.out.println(str); 
     } 
    } 
} 

Per convenzione, il metodo predominante utilizza la stessa firma (con tipo di ritorno) sia nella classe di super e sottoclasse. Nel codice sopra riportato, il tipo restituito del metodo getList() nello SuperClass è List e nella sottoclasse il tipo restituito è ArrayList. Come funziona l'override del metodo qui?

A proposito, è ovvio che ArrayList è un'implementazione dell'interfaccia List, ma come si fa il compilatore trattare il tipo di ritorno qui mentre l'override del metodo getList()?

Devo credere a qualcosa di simile ... Il tipo di ritorno del metodo sottoposto a override può essere un sottotipo del tipo di ritorno del metodo sottoposto a override.

+0

Non sembra esserci una buona ragione per dichiarare 'SubClass.list' come' list' (piuttosto che un 'ArrayList'). –

+0

@ MichaelBrewer-Davis - Potrebbe rendere le cose più belle quando stai usando 'SubClass' direttamente invece di trattarlo come un' SuperClass'. –

+0

@Brendan - Stavo parlando della variabile membro (privata) che è troppo generica, non del metodo troppo specifico. La covarianza nel metodo è il sole e le farfalle. –

risposta

19

Sì.

All'inizio di Java non era il caso, ma è stato modificato in Java 5.0.

Non è possibile avere due metodi nella stessa classe con firme che differiscono solo per tipo di ritorno. Fino alla versione J2SE 5.0, era anche vero che una classe non poteva sovrascrivere il tipo di ritorno dei metodi che eredita da una superclasse. In questo suggerimento si apprenderà una nuova funzionalità in J2SE 5.0 che consente tipi di ritorno covarianti. Ciò significa che un metodo in una sottoclasse può restituire un oggetto il cui tipo è una sottoclasse del tipo restituito dal metodo con la stessa firma nella superclasse. Questa funzione elimina la necessità di un controllo e casting di tipo eccessivo.

La fonte di queste informazioni non è più disponibile sugli interwebs.

+0

Il link è morto. – Ghos3t

3

Sì, è corretto. Poiché ArrayList è un elenco, è possibile restituire un oggetto Array quando il metodo originale ha restituito un elenco.

4

Nella programmazione orientata agli oggetti, un tipo di ritorno covariante di un metodo è uno che può essere sostituito da un tipo "più stretto" quando il metodo è sovrascritto in una sottoclasse. Un linguaggio notevole in cui questo è un paradigma abbastanza comune è il C++. tipi restituiti covarianti sono state (parzialmente) consentita nel linguaggio Java dopo il rilascio di JDK5.0, quindi il seguente esempio non sarebbe compilare una versione precedente:

// Classes used as return types: 

class A { 
} 

class B extends A { 
} 

// "Class B is more narrow than class A" 
// Classes demonstrating method overriding: 

class C { 
    A getFoo() { 
     return new A(); 
    } 
} 

class D extends C { 
    B getFoo() { 
     return new B(); 
    } 
} 

Più specificamente, covariante (bersaglio ristretto) o controvariante (da stretto a più ampio), il tipo di ritorno si riferisce a una situazione in cui il tipo di ritorno del metodo di sovrascrittura è cambiato in un tipo correlato (ma diverso da) al tipo di ritorno del metodo sovrascritto originale.

La relazione tra i due tipi di ritorno covarianti è solitamente quella che consente la sostituzione di un tipo con l'altro, seguendo il principio di sostituzione di Liskov.

Questo di solito implica che i tipi di restituzione dei metodi di sovrascrittura saranno sottotipi del tipo restituito del metodo sottoposto a override. L'esempio sopra illustra specificamente un caso del genere. Se la sostituzione non è consentita, il tipo restituito è invariante e causa un errore di compilazione.

Riferimento: https://en.wikipedia.org/wiki/Covariant_return_type

+0

https://en.wikipedia.org/wiki/Covariant_return_type –