可以将一个类的定义放在另一个类的内部定义,这就是内部类。
内部类是一个非常有用的特性。因为它允许你把一些逻辑相关的类组织在一起,并控制位于内部的类的可视性。
创建内部类的方式:把类的定义置于外围类的里面:
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