内部类:将一个类定义到另一个类内部。内部类是一种代码隐藏机制,并且内部类对象了解外围类,并能够与之通信。(内部类不是组合??(暂时不知道如何解释))
1 package com.slowalker.inner; 2 3 public class Parcel1 { 4 class Contents{ 5 public Contents() { 6 System.out.println("Contents gener"); 7 } 8 9 private int i = 11; 10 public int value() {return i;} 11 } 12 13 class Destination{ 14 private String label = ""; 15 Destination(String whereTo){ 16 label = whereTo; 17 } 18 String readLabel() {return label;} 19 } 20 21 public void ship(String dest) { 22 Contents c = new Contents(); 23 Destination d = new Destination(dest); 24 System.out.println(d.readLabel()); 25 } 26 27 public static void main(String[] args) { 28 Parcel1 p = new Parcel1(); 29 p.ship("Tasmania"); 30 } 31 }
上例中定义了一个Parcel1的外部类,其中定义了两个内部类,在使用内部类时,就是正常的访问机制,一个内部类对象调用内部类方法。
package com.slowalker.inner;
public class Parcel2 {
class Contents{
public Contents() {}
private int i = 11;
public int value() {return i;}
}
class Destination{
private String label = "";
Destination(String whereTo){
label = whereTo;
}
String readLabel() {return label;}
}
public void ship(String dest) {
Contents c = new Contents();
Destination d = new Destination(dest);
System.out.println(d.readLabel());
}
public static void main(String[] args) {
Parcel2 p = new Parcel2();
p.ship("Tasmania");
Parcel2.Contents c = p.new Contents();
Parcel2.Contents d = new Parcel2().new Contents(); //创建内部类对象,必须通过外部类引用
int a = c.value();
System.out.println(a);
System.out.println(c.value());
}
}
public class Parcel2 {
class Contents{
public Contents() {}
private int i = 11;
public int value() {return i;}
}
class Destination{
private String label = "";
Destination(String whereTo){
label = whereTo;
}
String readLabel() {return label;}
}
public void ship(String dest) {
Contents c = new Contents();
Destination d = new Destination(dest);
System.out.println(d.readLabel());
}
public static void main(String[] args) {
Parcel2 p = new Parcel2();
p.ship("Tasmania");
Parcel2.Contents c = p.new Contents();
Parcel2.Contents d = new Parcel2().new Contents(); //创建内部类对象,必须通过外部类引用
int a = c.value();
System.out.println(a);
System.out.println(c.value());
}
}
如果我们需要使用内部类对象,则必须通过外部类的对象去引用。内部类所包含的方法,必须通过内部类调用。
在内部类中,可以访问外部类的方法和域
1 package com.slowalker.inner; 2 3 interface Selector{ 4 boolean end(); 5 Object current(); 6 void next(); 7 } 8 9 10 public class Sequence { 11 private Object[] items; 12 private int next; 13 14 public Sequence(int size) { 15 items = new Object[size]; 16 } 17 18 public void add(Object x) { 19 if (next < items.length) { 20 items[next++] = x; 21 } 22 } 23 24 private class SequenceSelector implements Selector{ //实现了接口的内部类 25 private int i = 0; 26 27 //items是外部类的成员,内部类可以直接使用 28 public boolean end() {return i == items.length;} 29 public Object current() {return items[i];} 30 public void next() {if (i < items.length) i++;} 31 32 } 33 34 public Selector selector() { 35 return new SequenceSelector(); 36 } 37 38 public static void main(String[] args) { 39 40 //外部类对象创建用来修改外部类成员 41 Sequence sequence = new Sequence(10); 42 for(int i = 0; i < 10; i++) { 43 sequence.add(Integer.toString(i)); 44 } 45 46 //内部类创建用来迭代外部类 47 Sequence.SequenceSelector selector = sequence.new SequenceSelector(); 48 49 while(!selector.end()) { 50 System.out.println(selector.current() + " "); 51 selector.next(); 52 } 53 } 54 }
当某个外部类创建了一个内部类对象时,内部类对象会捕获一个指向该外部类的引用。内部类可以通过该引用使用该外部类对象的成员。
如果在内部类需要引用创建该内部类对象的外部类对象可以使用 外部类类名+".this".
package com.slowalker.inner; public class DotThis { void f() {System.out.println("DotThis.f()");} public class Inner{ public DotThis outner() { return DotThis.this; } } public Inner inner() { return new Inner(); } public static void main(String[] args) { DotThis dt = new DotThis(); DotThis.Inner i = dt.inner(); i.outner().f(); } }