内部类
可以将一个类的定义放在另一个类的定义内部,这就是内部类
创建内部类
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 readLabel() {return label;}
}
public void ship(String dest) {
Contents c=new Contents();
Destination d=new Destination(dest);
System.out.println(d.readLabel());
}
public static void main(String[] args) {
Parcel1 p=new Parcel1();
p.ship("Tasmania");
}
}
如果想从外部类的非静态方法之外的任意位置创建某个内部类的对象,那么必须具体指明这个对象的类型: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();
}
}
}
使用.this与.new
如果需要生成对外部类对象的引用,可以使用外部类的名字后面紧跟圆点和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();
}
}
告知某些其他对象去创建其某个内部类的对象,需要使用.new语法
public class DotNew {
public class Inner {}
public static void main(String[] args){
DotNew dn=new DotNew();
DotNew.Inner dni=dn.new Inner();
}
}
在拥有外部类对象之前是不可能创建内部类对象的,除非你创建的是嵌套类(静态内部类)
在方法和作用域内的内部类
在方法的作用域内(而不是一个类的作用域类)创建一个完整的类,这被称为局部内部类
public class Parcel5 {
public Destination destination(String s) {
class PDestination implements Destination {
private String label;
private PDestination(String whereTo) {
label=whereTo;
}
public String readLabel() {return label;}
}
return new PDestination(s);
}
public static void main(String[] args){
Parcel5 p=new Parcel5();
Destination d=p.new Destination("Tasmania");
}
}
匿名内部类
创建一个继承自Contents的匿名类的对象,通过new表达式返回的引用被自动向上转型为对Contents的引用
return new Contents(){...}
嵌套类
如果不需要内部类与外部类对象之间有联系,那么可以将内部类声明为static,称为嵌套类。
特点:
1.要创建内部类对象,并不需要其外部类的对象
2.不能从嵌套类的对象中访问非静态的外围类对象
接口内部的类
正常情况下,不能在接口中放置任何代码,但嵌套类可以作为接口的一部分。
public interface ClassInInterface {
void howdy();
class Test implements ClassInInterface{
public void howdy(){
System.out.println("Howdy!");
}
public static void main(String[] args){
new Test().howdy();
}
}
}
从多层嵌套类中访问外部类成员
一个内部类被嵌套多少层并不重要,它能透明地访问所有它所嵌套入的外围类的所有成员
为什么需要内部类
每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口)实现,对于内部类没有影响
使用内部类,还可以获得其他一些特性:
1 内部类可以有多个实例,每个实例都有自己的状态信息,并且与外围类的信息相互独立
2在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或继承同一个类
3 创建内部类对象的时刻并不依赖于外围类的创建
4 内部类没有令人迷惑的‘is-a’关系,它就是一个独立的实体。
参考书《Java编程思想》