可以将一个类的定义放在另一个类的内部定义,这就是内部类。
内部类是一个非常有用的特性。因为它允许你把一些逻辑相关的类组织在一起,并控制位于内部的类的可视性。
创建内部类的方式:把类的定义置于外围类的里面:
public class Parcel1 { class Contents{ private int i = 11; public int value() {return i;} } class Destination{ private String label; Destination(String whereTo){ label = whereTo; } String readLable() {return label;} } public void ship(String dest) { Contents c = new Contents(); Destination d = new Destination(dest); System.out.println(d.readLable()); } public static void main(String[] args) { Parcell p = new Parcel1(); p.ship("Zhengy"); } }
在我们在ship()方法里面使用内部类的时候,与使用普通类没有什么区别,在这里,实际的区别就是内部类的定义是嵌套在Parcel1中。
下面我们尝试在类中定义一个方法,该方法返回一个指向内部类的医用。
//内部类 public class Parcel2 { class Contents{ private int i = 11; public int value() {return i;} } class Destination{ private String label; Destination(String whereTo){ label = whereTo; } String readLable() {return label;} } public Destination to(String s) { return new Destination(s); } public Contents contents() { return new Contents(); } public void ship(String dest) { Contents c = new Contents(); Destination d = new Destination(dest); System.out.println(d.readLable()); } public static void main(String[] args) { Parcel2 p = new Parcel2(); p.ship("南京"); Parcel2 q = new Parcel2(); Parcel2.Destination d = q.to("北京"); Parcel2.Contents c = q.contents(); } }
如果想在类外创建某个内部类的对象,必须像main()方法那样,具体指明这个对象的类型:OuterClassName.InnerClassName。
当创建一个内部类的对象时,此对象与创建它的外围对象之间就有了一种联系,所以它能够访问其外围对象的所有成员,而不需要任何特殊条件。下面的例子说明了这一点:
///链接到外部类 //类似迭代器 interface Selector{ boolean end(); //判断序列是否迭代结束 Object current(); //获取当前元素 void next(); //下一个元素 } //序列类(外围类) public class Sequence { //数组用于保存元素 private Object[] items; //当前追加索引 private int next = 0; public Sequence(int size) {items = new Object[size];} //向数组追加元素 public void add(Object x) { if(next < items.length) items[next++] = x; } //内部类:迭代器(可以访问外围对象的所有成员),这里用来迭代序列中所有元素 private class SequenceSelector implements Selector{ private int i = 0; public boolean end() {return i == items.length;} public Object current() {return items[i];} public void next() { if(i < items.length) i++; } } //创建迭代器对象 public Selector selector() { return new SequenceSelector(); } public static void main(String[] args) { Sequence sequence = new Sequence(10); for(int i=0;i<10;i++) { sequence.add(Integer.toString(i)); } Selector selector = sequence.selector(); while(!selector.end()) { System.out.print(selector.current() + " "); selector.next(); } } }
输出结果如下:
0 1 2 3 4 5 6 7 8 9
上面演示了一个:"迭代器"设计模式的例子。
在内部类中如果需要创建对外部类对象的引用,可以使用外部类的名字后面跟着.this。下面演示如何使用.this:
///使用.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(); } }
输出如下:
DotThis.f()
有时你可能想要告知某些其他对象,去创建其某个内部类的对象,要实现此目的。你必须在new 表达式中提供对其外部类对象的引用,这是需要使用.new语法,如下:
///.new
public class DotNew {
public class Inner{
public void f(){
System.out.print("test");
}
}
public static void main(String[] args) {
DotNew dn = new DotNew();
DotNew.Inner dni = dn.new Inner();
dni.f();
}
}
想要直接创建内部类的对象,不可以直接引用外部类的名字DotNew,而是必须使用外部类的对象来创建该内部类对象,就像上面的程序中所看到的那样。在拥有外部类对象之前是不可能创建内部类对象的,这是因为内部类对象会暗暗地连接到创建它的外部类对象上。
但是,如果创建的是嵌套类(静态内部类),那么它就不需要对外部类对象的引用。
原文:https://www.cnblogs.com/zyly/p/10596268.html