可以将一个类的定义放在另一个类的定义内部,这就是内部类。内部类可以使用外部类的私有属性而不会破坏封装性,而且内部类可以访问外部类的所有方法与属性,但static的内部类只能访问外部类的静态属性与方法。内部类又可以分为成员内部类、静态内部类、局部内部类和匿名内部类。
首先说下成员内部类,类似于外部类的实例属性或函数,成员类有public/private/default权限修饰符。一个成员类实例必然所属一个外部类实例,成员类可访问外部类的任一个实例字段或实例函数。成员类内部访问其所属外部类实例采用"OuterClass.this .属性 "的形式,在内部类中访问实例变量:"this.属性"。 对于给定的一个外部类实例outerClass,可以直接创建其内部类实例,语法形式为"OuterClass.InnerClass innerClass=outerClass.new InnerClass()",成员类不能与外部类重名。不能在成员类中定义static字段、方法和类。因为一个成员类实例必然与一个外部类实例关联,而且静态属性是在加载类的时候创建,这个时候内部类还没有被创建成员类不能是接口,因为成员类必须能被某个外部类实例化,而接口不能实例化。成员类的显著特性就是成员类能访问它的外部类实例的任意字段与方法。
public class Parcel1 {
private String str="hello";
public class Contents{
private int i=11;
public int value(){
return i;
}
}
class Destination{
private String label;
Destination(String whereTo){
label=whereTo;
}
String readLabel(){
return Parcel1.this.str+","+label;
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Parcel1 p=new Parcel1();
Parcel1.Contents c=p.new Contents();
System.out.println(c.value());
Parcel1.Destination d=p.new Destination("world");
System.out.println(d.readLabel());
}
}
注意在创非静态内部类对象时,一定要先创建相应的外部类对象。非静态内部类对象有着指向其外部类对象的引用,可以访问创建它的外部类对象的内容,甚至包括私有变量。非静态内部类不能声明本类的static成员,只有静态内部类才可以声明一个static成员。成员内部类可以直接访问外部类的非静态或静态成员、方法。
静态内部类:类声明中包含static关键字的内部类,在静态内部类中只能访问外部类的静态成员。在外部类的外部,要创建一个静态内部类对象不需要外部类对象:Outer.Inner in = new Outer.Inner();
public class Parcel11 {
private static class ParcelContents implements Contents{
private int i=11;
public int value(){
return i;
}
}
protected static class ParcelDestination implements Destination{
private String label;
private ParcelDestination(String whereTo){
label=whereTo;
}
public String readLabel(){
return label;
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Parcel11.ParcelContents c=new Parcel11.ParcelContents();
System.out.println(c.value());
Parcel11.ParcelDestination d=new Parcel11.ParcelDestination("hello");
System.out.println(d.readLabel());
}
}
静态内部类没有指向外部类的引用,可以定义任何静态和非静态成员,在静态内部类中只能访问外部类的静态成员。
如果我们在用一个内部类的时候仅需要创建它的一个对象并传给外部类,就可以创建一个局部内部类并返回。局部内部类: 在外部类的方法中定义的内部类,与局部变量类似,在局部内部类前不可以加修饰符public和private,其作用域为定义它的代码块,局部内部类不仅可以访问外部类的实例变量,还可以访问局部变量,但要求局部变量必须为final的
在外部类的外部不可创建局部内部类对象,只能在局部内部类所在的方法中创建。
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);
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Parcel5 p=new Parcel5();
Destination d=p.destination("Tasmania");
System.out.println(d.readLabel());
}
}
匿名内部类:一种特殊的局部内部类,没有名字,也没有class、extends、implements关键字,无构造,用一种隐含的方式实现一个接口或继承一个类,并且只能创建一次实例。匿名内部类属于局部内部类,那么局部内部类的所有限制都对其生效。匿名内部类是唯一一种无构造方法的类,因为构造器的名字必须和类名相同,而匿名内部类没有类名。
实现方式:在某个语句中,new 父类/父接口名字(){ 类体中实现方法 }
public class Parcel7 {
public Contents contents(){
return new Contents(){
private int i=11;
public int value() {
// TODO Auto-generated method stub
return i;
}
};
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Parcel7 p=new Parcel7();
Contents c=p.contents();
System.out.println(c.value());
}
}
public class Parcel9 {
public Destination destination(final String dest){
return new Destination(){
private String label=dest;
public String readLabel() {
// TODO Auto-generated method stub
return label;
}
};
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Parcel9 p=new Parcel9();
Destination d=p.destination("Tasmania");
System.out.println(d.readLabel());
}
}