2015-01-06 10 views
8

Hãy nói rằng tôi có đoạn mã sau:Làm thế nào để làm cho 'this` điểm đến các lớp bên ngoài nơi lớp bên trong có tên cùng một phương pháp

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

Làm thế nào tôi có thể tham khảo getIterable của lớp bên ngoài từ bên trong lớp học cùng tên?

MyStream.this nên trỏ đến lớp bên trong ở đây, phải không? Làm thế nào để hiển thị một lớp bên ngoài có cùng tên?

+1

Bạn có thể sử dụng biến cục bộ trong phương thức chắp thêm và đặt nó thành –

+0

@RichardTingle đó là giải pháp hiện tại của tôi, nhưng nó không thanh lịch. tôi tự hỏi nếu có một giải pháp tốt hơn. – HuStmpHrrr

Trả lời

8

Nếu bạn gọi MyStream.this từ lớp vô danh nó sẽ trỏ đến các lớp bên ngoài để mã dưới đây sẽ làm việc như bạn mong đợi:

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

(nếu nó không bạn sẽ nhận được một StackOverflowError).

Lý do tại sao nó hoạt động là an anonymous class is an inner class.


dụ đơn giản mà in 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

Bạn đã thử cái này chưa? Tôi sẽ ngạc nhiên nếu nó hoạt động, bởi vì lớp vô danh được khởi tạo không phải là một lớp bên trong của 'MyStream'. –

+0

Tôi đã thử trên một ví dụ đơn giản và có vẻ như nó hoạt động. – assylias

+0

OK, đủ công bằng rồi. Tôi đoán tôi sai rồi. Và ngạc nhiên. –

1

MyStream.this không trỏ đến các lớp bên trong. Lớp bên trong là ẩn danh. Nó có thể gây nhầm lẫn cho bạn bởi vì bạn đã sử dụng new MyStream() {...}, nhưng trên thực tế đó là một lớp bên trong mới, có tên nội bộ và cú pháp new MyStream() {...} chỉ đơn giản là phục vụ để thay thế cú pháp SomeClass extends MyStream.

Điều đáng chú ý là các lớp bên trong cả kéo dàiMyClass và là lồng nhau trong đó. Điều này có nghĩa là cả hai tài khoản superMyClass.this đều tồn tại và là tham chiếu MyClass, nhưng chúng là hai cá thể đối tượng riêng biệt. super trỏ đến bản thân lớp bên trong, nhưng nhìn vào nó như thể nó là MyClass, trong khi MyClass.this là đối tượng kèm theo.

Các vấn đề liên quan