2015-09-16 10 views
9

Wdrażam wzór gościa dla projektu i zdaję sobie sprawę, że mogę zapisać pewne pismo, mając domyślną implementację akceptacji.Jaki jest statyczny typ "tego" w domyślnych interfejsach Java 8?

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

Jednak jeśli statyczny typ this postanawia visitable ta implementacja nie będzie działać tak, co jest statyczny typ this w tej sytuacji?

+0

Co czy uważasz, że tak powinno być? – biziclop

+4

Czy próbowałeś tego i widziałeś, co się dzieje? –

+0

Jaka jest twoja definicja 'Gość'? – RealSkeptic

Odpowiedz

6

Ponieważ w twoim kontekście, this jest używany jako typ parametru, wywołanie zostanie rozstrzygnięte na Visitor#visit(Visitable) podczas kompilacji i runtime. W ten sposób nic nie zyskujesz, próbując stworzyć domyślną metodę w tym scenariuszu.

Tylko raz this można stosować polimorficznie jest podczas używania go jako odbiornika:

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

    public void bar(int i); 
} 
+0

Stworzyłem mały przykład, aby przetestować to i typ rzeczywiście zakończył się byciem 'Visitable'. Musiałem zastąpić metodę 'accept' w każdej klasie implementacji, aby uzyskać pożądane zachowanie, mimo że implementacja dla każdej klasy była taka sama jak domyślna. Miałem nadzieję, że Java zasadniczo skopiuje domyślną metodę do każdej klasy implementacji, ale tak nie jest. – en4bz

+2

W rzeczywistości tak nie jest, ponieważ oznaczałoby to, że nie można było użyć metod domyślnych w podklasach, które zostały skompilowane przed dodaniem metody - dlatego właśnie zostały dodane domyślne metody. – Clashsoft

+1

@Clashsoft 'Jedynym czasem, w którym można go użyć polimorficznie, jest użycie go jako odbiornika:' Ale nawet wtedy otrzymujesz standardową dynamiczną wysyłkę Javy, nie możesz odwoływać się do żadnej metody, która nie jest zdefiniowana przez ' Obiekt', bieżący interfejs lub dowolny z jego superinterfejsów. Tak więc typ kompilacji 'this' jest zawsze aktualną klasą, tak jak i wszędzie indziej. – biziclop

4

można dowiedzieć się tego poprzez eksperyment:

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

Powyższe wyjścia Am visiting a generic Visitable