Java内部类详解(一):内部类的定义和访问外部类

一、什么是内部类

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

二、链接到外部类

当生成一个内部类的对象时,此对象与制造它的外围对象之间就有了一种联系,所以它能访问其外围对象的所有成员,此外,内部类自动拥有对其外围类所有成员的访问权

下面例子展示内部类如何链接到外部类:

Selector.java:

public interface Selector {
	boolean end();
	Object current();
	void next();

}

Student.java:

package innerClass;

public class Student {
	private int id;
	private String name;
	
	@Override
	public String toString() {
		return "Student [id=" + id + ", name=" + name + "]";
	}
	/**
	 * @return the id
	 */
	public int getId() {
		return id;
	}
	/**
	 * @param id the id to set
	 */
	public void setId(int id) {
		this.id = id;
	}
	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}
	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}
	
	

}

Sequence.java:

public class Sequence {
	private Object[] items;
	private int next = 0;

	public Sequence(int size) {
		items = new Object[size];
	}

	public void add(Object x) {
		items[next++] = x;
	}

	private class SequenceSelector implements Selector {
		private int i = 0;
		/*
		 * 检查items序列是否到末尾
		 */
		@Override
		public boolean end() {

			return i == items.length;
		}
        /*
         * 访问当前序号为i的items对象
         */
		@Override
		public Object current() {

			return items[i];
		}
       /*
        * 移到序列中的下一个items对象
        */
		@Override
		public void next() {
			if (i < items.length) {
				i++;
			}

		}
		
	/*
	 * 内部类生成对外部对象的引用
	 */
     public Sequence outer() {
    	 return Sequence.this;
     }
     
	}
/*
 * 外部类返回一个指向内部类SequenceSelector的引用
 */
	public Selector selector() {
		return new SequenceSelector();
	}

	public static void main(String[] args) {
		Sequence sequence = new Sequence(10);
		//插入数据
		for (int i = 0; i < 9; i++) {
			Student student=new Student();
			student.setId(i);
			student.setName("张三"+i);
			sequence.add(student);

		}
		SequenceSelector selector = (SequenceSelector) sequence.selector();
		/*
		 * 使用.this实现的对外部类的引用,再添加一个student对象
		 */
		Student student=new Student();
		student.setId(9);
		student.setName("张三9");
		selector.outer().add(student);
		/*
		 * 遍历Sequence的items
		 */
		while (!selector.end()) {
			System.out.println(selector.current());
			selector.next();
		}
		
	}

}

运行结果:

Student [id=0, name=张三0]
Student [id=1, name=张三1]
Student [id=2, name=张三2]
Student [id=3, name=张三3]
Student [id=4, name=张三4]
Student [id=5, name=张三5]
Student [id=6, name=张三6]
Student [id=7, name=张三7]
Student [id=8, name=张三8]
Student [id=9, name=张三9]

上面例子使用到了“迭代器”设计模式,SequenceSelector是提供Selector功能的private内部类。其方法end()、current()和next()都使用到其外围类的items。而items是外围类Sequence中的private字段。

那么内部类为何可以直接访问其外围类的所有方法和字段呢?这是因为当某个外围类的对象创建了一个内部类对象时,此内部类对象必定会秘密捕获一个指向那个外围类对象的引用(此过程由编译器完成)。内部类对象访问此外围类的成员就是用此引用来选择外围类对象。

四、.this的使用

上面例子使用到了.this,用于生成对外部类对象的引用,这样产生的引用自动地具有正确类型,这一点在编译器就被知晓并受到检查,因此没有任何运行时开销。

五、.new的使用

上面例子中外部类有一个selector()方法用于返回内部类的引用。如果不使用这个方法也是可以的,可以使用在new表达式中提供对外部类的引用,这时必须使用到.new语法。
那么对应创建内部类的语句:

SequenceSelector selector = (SequenceSelector) sequence.selector();

可以改成这样:

SequenceSelector selector =sequence.new SequenceSelector();

两种创建方式都可以,.new语法就是用于通过外部类对象创建某个内部类对象。


参考书籍:《Java编程思想》

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值