Java基础 -- 内部类

可以将一个类的定义放在另一个类的内部定义,这就是内部类。

内部类是一个非常有用的特性。因为它允许你把一些逻辑相关的类组织在一起,并控制位于内部的类的可视性。

一 创建内部类

创建内部类的方式:把类的定义置于外围类的里面:

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和.new

在内部类中如果需要创建对外部类对象的引用,可以使用外部类的名字后面跟着.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,而是必须使用外部类的对象来创建该内部类对象,就像上面的程序中所看到的那样。在拥有外部类对象之前是不可能创建内部类对象的,这是因为内部类对象会暗暗地连接到创建它的外部类对象上。

但是,如果创建的是嵌套类(静态内部类),那么它就不需要对外部类对象的引用。

四 内部类与向上转型

猜你喜欢

转载自www.cnblogs.com/zyly/p/10596268.html