2015-09-16 1 views
9

Sto implementando il modello di visitatore per un progetto e ho realizzato che potrei essere in grado di salvare un po 'digitando l'implementazione predefinita di accettare come segue.Qual è il tipo statico di `this` nelle interfacce predefinite di Java 8?

public interface Visitable { 
    default public void accept(Visitor v) { 
     v.visit(this); 
    } 
} 

Tuttavia, se il tipo statico di this risolve a visitabile questa implementazione non funziona quindi qual è il tipo statico di this in questa situazione?

+0

Cosa pensi che dovrebbe essere? – biziclop

+4

Hai provato e visto cosa succede? –

+0

Qual è la tua definizione di "Visitatore"? – RealSkeptic

risposta

6

Poiché, nel proprio contesto, this viene utilizzato come tipo di parametro, la chiamata verrà risolta in Visitor#visit(Visitable) in fase di compilazione e di runtime. Pertanto, non ottieni nulla dal provare a creare un metodo predefinito in questo scenario.

L'unica volta this può essere utilizzato polimorfico è quando lo si utilizza come il ricevitore:

public interface Foo 
{ 
    public default void bar() 
    { 
     this.bar(1); 
    } 

    public void bar(int i); 
} 
+0

Ho creato un piccolo esempio per testarlo e il tipo ha effettivamente finito per essere "Visitabile". Ho dovuto sovrascrivere il metodo 'accept' in ogni classe di implementazione per ottenere il comportamento che volevo anche se l'implementazione per ogni classe era la stessa del default. Speravo che Java eseguisse essenzialmente un copia-incolla del metodo predefinito in ogni classe di implementazione, ma non è questo il caso. – en4bz

+2

In effetti, questo non è il caso, perché significherebbe che non è possibile utilizzare i metodi predefiniti in sottoclassi compilati prima dell'aggiunta del metodo, motivo per cui sono stati aggiunti i metodi predefiniti in primo luogo. – Clashsoft

+1

@Clashsoft 'L'unica volta che questo può essere usato polimorficamente è quando lo si usa come ricevitore:' Ma anche allora tutto ciò che si ottiene è l'invio dinamico standard di Java, non è possibile fare riferimento a nessun metodo che non sia definito da ' Object', l'interfaccia corrente o una delle sue superinterfacce. Quindi il tipo di compilazione di 'this' è sempre la classe corrente, come del resto è ovunque. – biziclop

4

È possibile calcolare questo fuori da esperimento:

public interface Visitable { 
    default public void accept(Visitor v) { 
     v.visit(this); 
    } 
} 

public class Vis1 implements Visitable { 

} 

public class Visitor { 
    public void visit(Visitable v) { 
     System.out.println("Am visiting a generic Visitable"); 
    } 

    public void visit(Vis1 v) { 
     System.out.println("Am visiting a Vis1"); 
    } 
} 

public class Main { 
    public static void main(String[] args) { 
     Visitor v = new Visitor(); 
     Vis1 v1 = new Vis1(); 
     v1.accept(v); 
    } 
} 

Le uscite di cui sopra Am visiting a generic Visitable