2015-01-06 16 views
8

Powiedzmy mam następujący kod:Jak `this` punkt do zewnętrznej klasy, w których wewnętrzna klasa ma taką samą nazwę metody

abstract class MyStream 
{ 
    public abstract Iterable<Integer> getIterable(); 

    public MyStream append(final int i) 
    { 
     return new MyStream() 
     { 
      @Override 
      public Iterable<Integer> getIterable() 
      { 
       return cons(/*outer class's*/getIterable(), i); 
      } 
     }; 
    } 

    public static Iterable<Integer> cons(Iterable<Integer> iter, int i) { /* implementation */ } 
} 

Jak mogę odwołać getIterable zewnętrznej klasy z wewnętrzną klasa o tej samej nazwie?

MyStream.this powinien wskazywać tutaj klasę wewnętrzną, prawda? Jak pokazać zewnętrzną klasę o tej samej nazwie?

+1

Można użyć zmiennej lokalnej w metodzie dołączania i ustawić ją jako –

+0

@RichardTingle to moje obecne rozwiązanie, ale nie jest eleganckie. Zastanawiam się, czy istnieje lepsze rozwiązanie. – HuStmpHrrr

Odpowiedz

8

Jeśli zadzwonisz MyStream.this od anonimowego klasy to będzie wskazywać na zewnętrznej klasy więc poniższy kod powinien działać zgodnie z oczekiwaniami:

return const(MyStream.this.getIterable(), i); 

(jeśli nie chcesz dostać StackOverflowError).

Powodem, dla którego działa, jest an anonymous class is an inner class.


uproszczony przykład drukująca outer 1:

public static void main(String args[]) { 
    MyClass c = new MyClass() { 
    @Override public String get() { return "outer"; } 
    }; 
    System.out.println(c.append(1).get()); 
} 

static abstract class MyClass { 
    public abstract String get(); 

    public MyClass append(final int i) { 
    return new MyClass() { 
     @Override public String get() { 
     return cons(MyClass.this.get(), i); 
     } 
    }; 
    } 

    public static String cons(String iter, int i) { return iter + " " + i; } 
} 
+1

Czy próbowałeś tego? Byłbym zaskoczony, gdyby zadziałało, ponieważ instancja anonimowej klasy nie jest wewnętrzną klasą "MyStream". –

+0

Próbowałem na prostszym przykładzie i wygląda na to, że działa. – assylias

+0

OK, w porządku, wystarczy. Chyba się mylę. I zaskoczony. –

1

MyStream.this nie wskazuje na wewnętrznej klasy. Wewnętrzna klasa to anonimowa. Może cię to zmylić, ponieważ użyłeś new MyStream() {...}, ale w rzeczywistości jest to nowa wewnętrzna klasa, która ma wewnętrzną nazwę, a składnia new MyStream() {...} służy po prostu do zastąpienia składni .

Warto zauważyć, że wewnętrzna klasa zarówno rozciągaMyClass i zagnieżdżona w nim. Oznacza to, że zarówno super, jak i MyClass.this istnieją i są odniesieniami MyClass, ale są to dwie odrębne instancje obiektów. super wskazuje na samą instancję klasy wewnętrznej, ale patrzy na nią tak, jak gdyby była to MyClass, podczas gdy MyClass.this jest otaczającym obiektem.

Powiązane problemy