2015-01-06 3 views
8

Lassen Sie uns sagen, dass ich den folgenden Code haben:Wie `this` Punkt auf der äußeren Klasse zu machen, wo die innere Klasse die gleiche Methode Namen hat

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 */ } 
} 

Wie kann ich getIterable der äußeren Klasse von der inneren Bezugs Klasse mit dem gleichen Namen?

MyStream.this sollte hier auf die innere Klasse zeigen, richtig? Wie zeige ich eine äußere Klasse mit demselben Namen an?

+1

Sie könnten eine lokale Variable innerhalb der Append-Methode verwenden und setzen Sie diese auf –

+0

@RichardTingle, das ist meine aktuelle Lösung, aber es ist nicht elegant. Ich frage mich, ob es eine bessere Lösung gibt. – HuStmpHrrr

Antwort

8

Wenn Sie MyStream.this aus der anonymen Klasse nennen es auf die äußere Klasse Punkt wird so unter dem Code sollte, wie Sie arbeiten erwarten:

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

(wenn es nicht täte, würde man eine Stackoverflow bekommen).

Der Grund, warum es funktioniert, ist, dass an anonymous class is an inner class.


vereinfachtes Beispiel, das outer 1 druckt:

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

Haben Sie das versucht? Ich wäre überrascht, wenn es funktionieren würde, weil die anonyme Klasse, die instanziiert wird, keine innere Klasse von 'MyStream' ist. –

+0

Ich habe versucht, ein einfacheres Beispiel und es scheint zu funktionieren. – assylias

+0

OK, fair genug dann. Ich glaube, ich liege falsch. Und überrascht. –

1

MyStream.this nicht auf die innere Klasse verweisen. Die innere Klasse ist anonym. Es kann Sie verwirren, weil Sie new MyStream() {...} verwendet haben, aber tatsächlich ist es eine neue innere Klasse, die einen internen Namen hat, und die new MyStream() {...} Syntax dient einfach dazu, die Syntax zu ersetzen.

Es ist erwähnenswert, dass die innere Klasse sowohl erstrecktMyClass und ist verschachtelten drin. Dies bedeutet, dass sowohl super als auch MyClass.this vorhanden sind und MyClass Referenzen sind, aber sie sind zwei verschiedene Objektinstanzen. super verweist auf die innere Klasseninstanz selbst, sieht aber so aus, als wäre es MyClass, während MyClass.this das umschließende Objekt ist.

Verwandte Themen