内部类
可以将一个类的定义放在另一个类的定义内部,这就是内部类。
1.创建内部类
最简单的创建内部类的方法就是把类的定义至于外围类里面。更典型的就是,外部类有一个方法,该方法返回一个指向内部的引用。
public class Parcel {
class Contents {
private int i = 1;
public int value() {
return i;
}
}
class Destination {
private String label;
Destination(String whereTo) {
label = whereTo;
}
String readLabel() {
return label;
}
}
public Destination to(String s) {
return new Destination(s);
}
public Contents contents() {
return new Contents();
}
public void ship(String dest) {
Contents c = contents();
Destination d = to(dest);
System.out.println(d.readLabel());
}
public static void main(String[] args) {
Parcel p = new Parcel();
p.ship("Tasmaina");
Parcel k = new Parcel();
Parcel.Contents c = k.contents();//外部类的方法返回内部类的引用
Parcel.Destination d = k.to("Borneo");
}
}
如果想从外部类的静态方法之外的其他位置创建某个内部类的对象必须像再main方法中那样指明对象的类型:OuterClass.InnerClass 。
2.链接到外部类
内部类可以访问外围类的方法和字段(所有权限),因为外围类的对象创建了一个内部类的对象时,此内部类会秘密地捕获一个指向外围类的对象引用,利用这个引用就可以访问外围类的字段和方法。
3. 使用.this和.new
在内部类中要生成对外类对象的引用可以使用:outerClassName.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 dt = new DotNew();
DotNew.Inner dni = dn.new Inner();
}
}
在拥有外部类对象之前是不可能创建内部类的,但是,如果创建的是 嵌套类(静态内部类) ,那么它就不需要对外部类对象的引用。
4.内部类与向上转型
在内部类实现了某个接口时,将内部类向上转型为基类或接口,可以很好的隐藏实现细节。特别是将内部类声名为private的时候,只有外部类可以访问它,完全隐藏了实现细节。
5. 在方法和作用域内的内部类
下面的例子是在方法的作用域创建了一个类,也称为局部内部类。
public interface Destination {
String readLabel();
}
public class Parcel5 {
public Destination destination(String s) {
class PDestination implements Destination {
private String label;
private PDestination(String whereTO) {
label = whereTO;
}
@Override
public String readLabel() {
return label;
}
}
return new PDestination(s);
}
public static void main(String[] args) {
Parcel5 p = new Parcel5();
Destination d= p.destination("beijing");
}
}
6.匿名内部类
public interface Contents {
int value();
}
public class Parcel7 {
public Contents contents() {
return new Contents() {
private int i = 10;
public int value() {
return i;
}
};
}
public static void main(String[] args) {
Parcel7 p = new Parcel7();
Contents c = p.contents();
System.out.println(c.value());
}
}
contents 方法将返回值的生成与返回值的类的定义结合在一起!这个类称之为匿名类。这种语法可以理解为:“创建一个继承自Contents的匿名类对象。“通过new表达式返回的引用被自动向上转型为对Contents的引用。
在这个匿名内部类用的是默认构造器,如果需要往构造器里面传递参数可以通过以下方式;
public abstract class Wrapping {
private int i;
public Wrapping(int x) {
i = x;
}
public abstract int value();
}
public class Parcel8 {
public Wrapping wrapping(int x) {
return new Wrapping(x) {
public int value() {
return x*6;
}
};
}
public static void main(String[] args) {
Parcel8 p = new Parcel8();
Wrapping w = p.wrapping(10);
System.out.println(w.value());
}
}