1. 一个Java程序就是一个类的集合。程序中的类有两种排列结构。
例如:classEnclosingClass{
……
class ANestedClass{
……
}
}
2. 在某些特殊情况下,也会将一个类放在另一个类的内部定义,这个定义在其他类内部的类被称为内部类(有时也叫嵌套类),包含内部类的的类则称为外部类(有时也叫宿主类)。
内部类的作用:
内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问。
3.
ü 内部类在外部类中有特权:内部类可以毫无限制地访问外部类的所有成员(包括私有成员)。但外部类不能访问内部类的实现细节,比如内部类的属性。
ü 编译之后,内部类也可产生单独的.class文件,文件名为:外部类名$内部类名.class
ü 和普通的外部类不同,内部类是外部类的一个成员,内部类对象不能单独存在,它必许依赖一个外部类对象
ü 使用匿名内部类在编写事件处理驱动的程序时用起来很方便。
ü 只有内部类才能够是私有的--安全机制,只有其外部类的方法才能够创建内部类对象。
ü 对于同一个包中的其他类来说,内部类能够隐藏起来(将内部类用private修饰即可)
3. 如果只需要为内部类建立一个对象,甚至不必为该类指定一个名字,这种类被称为匿名内部类。
如果满足下面的一些条件,使用匿名内部类是比较合适的:
ü 只用到类的一个实例
ü 类在定义后马上用到
ü 类非常小(推荐在4行代码以下)
ü 给类命名并不会导致你的代码更容易被理解
4. 内部类也可以在方法或语句块中,称为局部内部类。局部内部类与成员类的基本特性相同,例如局部内部类的实例属性必属于其外部类的一个实例,可以通过外部类.class引用外部类的实例等,但它只能使用方法或语句块中的final常量。
例如:
class A{
public void show(){
final int a = 10;
class B{
B(){
System.out.println(a);
}
}
}
}
内部类可以被定义为抽象类或接口,但必须被其他的内部类继承或实现。非静态内部类不能声明static成员,只有静态的内部类可以声明static成员。
5.没有名字的内部类称为匿名内部类。
普通类:
class 类名 implementsActionListener{
public voidactionPerformed(ActionEvent e){…}
}
new 类名();
匿名内部类:
new ActionListener(){
public voidactionPerformed(ActionEvent e){ … }
};
由于匿名内部类没有名称,因此创建匿名内部类对象时,new运算符后是超类或接口的名称,其后的{}内部为匿名类的定义(匿名类对象的创建和匿名类的声明是在一起的)。
6. 匿名类不能是抽象类,因为系统在创建匿名类的时候,会立即创建匿名类的对象。因此不允许将匿名类定义成抽象类。
ü 匿名类不能有构造方法,因为匿名类没有类名,无法定义构造方法,但匿名类可以定义实例初始化块,通过实例初始化块来完成构造方法需要完成的事情。
ü 匿名类不能定义任何静态成员、方法和类;
ü 匿名类不能是public、protected、private、static;
ü 只能创建匿名类的一个实例。
7. 内部类可以声明为static或非static,也可以是private、protected、public以及默认的各种访问控制修饰符,用static修饰的称为静态内部类;没有用它修饰的简称为内部类。
静态内部类没有父类,不能引用外部类实例成员或其他内部类成员。
注意:
ü 静态内部类可以访问外部类的任一静态字段或静态方法。
ü 像静态方法或静态字段一样,静态内部类有public、private、default修饰。
ü 静态内部类不能与外部类同名。
ü 像外部类的静态方法一样,不能直接访问外部类的实例字段和实例方法。
ü 静态内部类只能定义于外部类的顶层代码或外部类其他静态成员类的顶层代码中(嵌套定义);不能定义于外部类的某个函数中。
如果一个静态内部类去掉其声明中的static关键字,将其定义移入其外部类的静方法或静态初始化代码段中,就成为了局部静态内部类。
局部静态内部类与静态内部类基本特性相同。