一、什么是内部类
一个定义在另一个类内部的类就称为内部类。
内部类是一种非常有用的特性,因为它允许你把一些逻辑相关的类组织在一起,并控制位于内部的类的可视性。
二、链接到外部类
当生成一个内部类的对象时,此对象与制造它的外围对象之间就有了一种联系,所以它能访问其外围对象的所有成员,此外,内部类自动拥有对其外围类所有成员的访问权。
下面例子展示内部类如何链接到外部类:
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编程思想》
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/44366.html