撰寫inner classes
- 若想要在outer class的non-static method之外產生一個inner class物件,須以OuterClassName.InnerClassName的形式指定該物件的型別。
public class Parcel2 {
class Contents { private int i = 11; public int value() { return i; } } // 一般會在outer class中建立method來產生inner class物件 public Contents contents() { return new Contents(); } public static void main(String[] args) { Parcel2 q = new Parcel2(); // Defining references to inner classes: Parcel2.Contents c = q.contents(); } } |
- outer class又可稱為enclosing class
- inner class可以存取enclosing class的所有成員,就好像inner class自己擁有這些成員一樣。
- non-static的inner class會自動記錄一個reference指向enclosing class的某個物件,後者就是此inner class物件的製造者。也就是一定會先有enclosing class物件才有辦法產生inner class物件。
使用.this及.new
- 若想在inner class中產生指向outer class物件的reference,可以使用OuterClassName.this。
public class DotThis { void f() { System.out.println("DotThis.f()"); } public class Inner { public DotThis outer() { return DotThis.this; } } public Inner inner() { return new Inner(); } public static void main(String[] args) { DotThis dt = new DotThis(); DotThis.Inner dti = dt.inner(); dti.outer().f(); } } |
- 若是想用outer class物件來產生inner class物件,可使用.new。
public class DotNew { public class Inner {} public static void main(String[] args) { DotNew dn = new DotNew(); DotNew.Inner dni = dn.new Inner(); } } |
位於methods和scopes內的inner class
- 基於兩個理由可能會想這樣做
- 想實作某個interface,使你可產生並回傳其reference。
- 希望在解決方案中設計某個class,又不希望此class給外界使用。
public class Parcel5 {
public Destination destination(String s) { class PDestination implements Destination {
private String label;
private PDestination(String whereTo) { label = whereTo; } public String readLabel() { return label; } } return new PDestination(s); } public static void main(String[] args) { Parcel5 p = new Parcel5(); Destination d = p.destination("Tasmania"); } } |
匿名的inner class
public class Parcel7 { public Contents contents() { return new Contents() { // Insert a class definition private int i = 11; public int value() { return i; } }; // Semicolon required in this case } public static void main(String[] args) { Parcel7 p = new Parcel7(); Contents c = p.contents(); } } |
- 產生某個匿名class的物件,此匿名class是繼承自Contents。
- new回傳的reference會被自動向上轉型為Contents reference。
巢狀類別
- static的inner class被稱為nested class。
- nested class意味著:
- 生成nested class的物件時不需要outer class的物件了。
- 無法在nested class的物件中存取outer class的non-static物件。
- 可擁有static data及nested class。
為什麼需要inner class
- 若你想同時繼承多個抽象或具象的class,必須用inner class來做到。
繼承inner class
- 繼承inner class時,指向outer class物件的reference必須被初始化。
class WithInner { class Inner {} } public class InheritInner extends WithInner.Inner { //! InheritInner() {} // Won’t compile InheritInner(WithInner wi) { wi.super(); } public static void main(String[] args) { WithInner wi = new WithInner(); InheritInner ii = new InheritInner(wi); } } |
沒有留言:
張貼留言