1.内部类如何做到自动拥有对其外围类所有成员的访问权?
当一个外围类创建一个内部类对象时,此内部对象必定会秘密地捕获一个指向那个外围类对象的引用。然后,当你访问此外围类的成员时,就是用那个引用来选择外围类的成员的。所以,你会发现:内部类的对象只能在其外部类对象相关的情况下被创建(内部类为非static时)。
//迭代器的实现
public 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();}
}
}
2.使用.this与.new
在拥有外部类对象之前是不可能创建内部类对象的,因为内部类对象会暗暗地链接到创建它的外部类对象上。但是如果创建的是静态内部类,它就不需要对外部类对象的引用。
public class Outer{
public class Inner{
public Outer outer(){
return Outer.this;//使用.this 返回外部类对象的引用
}
}
public Inner inner(){return new Inner();}
}
public class DotNew{
public class Inner(){}
public static void main(String[] args){
DotNew dn = new DotNew();
DotNew.Inner dni = dn.new Inner();//使用.new
}
}
3.内部类与向上转型
当将内部类向上转型为其基类,尤其是转型为一个接口的时候,内部类就有了用武之地。
public interface Destination{
String readLabel();
}
public interface Contents{
int value();
}
class Parce{
private class PContents implements Contents{
private int i =11;
public int value(){return i;}
}
public class PDestination implements Destination{
private String label;
private PDestination(String whereTo){
lable = whereTo;
}
public String readLable(){return label;}
public Destination destiantion(String s){
return new PDestination(s);
}
..
}
}
public class Test{
public static void main(String[] args){
//下面访问是错误的
//Parce.PContents pc = p.new PContens();
}
}
注:内部类PContents是private,所以除了Parce,没有人能够访问他。PDestination 是protected,所以只有Parce以及其子类,还有Parce同包中的类可以访问它。
private 内部类给类的设计者提供一种途径,通过这种方式可以完全阻止任何依赖于类型的编码。
4.匿名内部类
public class ParcleA{
class MyContents implements Contents{
private int i =11;
public int value(){return i;}
}
public Contents contents(int i){return new MyContents();//这里不要求i为final}
}
public class ParacleB{
public Destination destination(final String dest){
return new Destination(){
private String label = dest;//因为dest在匿名内部类中直接被使用
publci String readLabel(){return label;}
}
}
}
注:*在ParcleA不要求变量i一定是fianl。因为i被传递给匿名类的基类的构造器,它并不会再匿名类内部被直接使用。*