Inner Class 这个机制是在JDK1.1版本之后才添加到java语言中的, 它的存在主要有两个目的:
- 可以让程序设计中逻辑上相关的类结合在一起
- Inner Class可以直接访问外部类的成员
按照Inner Class声明的位置,大致上可以把它分成两种, 一个是类成员式的,就是像属性,方法一样. 把一个类声明为另一个类的成员. 第二个方法是区域式, 也就是把类声明在一个方法之中. 由这两种方式所派生出来的,按存在的范围又分成四种级别, 第一是类级别的, 第二是对象级别的, 第三是区域变量级别,第四是匿名级别.前两个级别是属于成员式的,后两个级别是属于区域式的.
成员式内部类
Inner Class的声明方式哏一般的类没什么两样,不过以成员式来说,既然是外部类的成员,那么别的类也可以访问它,因此Inner Class 可以使用任一个访问权修饰符. 类级别的Inner Class就是加 了static这个修饰符, 让别的类在访问时可以直接通过外部类的名称来访问. 而成员级别的Inner Class 就必须无产生外部类的对象后,才能通过这个对象来访问.
public class InnerClasses {
private static String staticAttribute = "Outter class static attribute";
private String instantiateAttribute = "Outter class instantiate attribute";
public void instantiateMethod(){
System.out.println("Outter class instantiate method");
}
public static void staticMethod(){
System.out.println("Outer class static method");
}
public static class StaticInnerClass{
public StaticInnerClass(){
System.out.println("static Inner class");
}
public void access(){
System.out.println(staticAttribute);
staticMethod();
}
}
public class InstantiateInnerClass{
public InstantiateInnerClass(){
System.out.println("Instantiate Inner class");
}
public void access(){
System.out.println(instantiateAttribute);
instantiateMethod();
}
}
}
public class InnerClassExample1 {
public static void main(String[] args) {
InnerClasses.StaticInnerClass in = new InnerClasses.StaticInnerClass();
in.access();
}
}
public class InnerClassExample2 {
public static void main(String[] args) {
InnerClasses.InstantiateInnerClass in;
InnerClasses out = new InnerClasses();
/**
* 注意这里写法,因为我们现在要访问的是对象级别的Inner Class,所以必须产生外部类的对象(out)后,
* 再通过out对象使用new 的方式来产生InstantiateInnerClass类的对象
*/
in = out.new InstantiateInnerClass();
in.access();
}
}
public class InnerClassExample3 {
private int att = 0;
public static void main(String[] args) {
new InnerClassExample3();
}
public InnerClassExample3() {
new Inner(2);
}
public class Inner{
private int att = 1;
public Inner(int att) {
System.out.println(att);
/*
* 访问的是Inner类的att属性
*/
System.out.println(this.att);
/*
* 访问的是外部类的att属性. 注意这里的this的用法
*/
System.out.println(InnerClassExample3.this.att);
}
}
}
Inner Class还可以声明为抽象类
public class AbstractInnerClassExample extends Outter5.StaticAbstractInnerClass{
}
class Outter5{
public static abstract class StaticAbstractInnerClass{
}
/**
* 对象级别的Inner Class只能被外部类中的其它Inner Class继承.
* 因为按extends语法后面接的必须是类的名称,对象级别的Inner Class没办法直接访问
*/
public abstract class AbstractInnerClass{
}
public class Inner extends AbstractInnerClass{
}
}
Inner class为接口
public class InnerInterfaceExample implements Outter6.StaticInnerInterface{
}
class Outter6{
static interface StaticInnerInterface{
}
interface InnerInterface{
}
class InnerClass implements InnerInterface{
}
}
区域式内部类
区域级别的变量指的是在方法中声明的变量,同样区域式的就是在方法中声明的类. 限制是如果要访问包含它的方法中的变量的话, 该变量必须是个学时,也就是说声明时要加上 "final"这个关键字. 这种类型的没有什么大用处.
public class InnerClassExample4 {
public static void main(String[] args) {
Outter4 out = new Outter4();
Object obj = out.methodWithInnerClass();
System.out.println(obj);
}
}
class Outter4{
/*
* 返回值只能用Object的对象类型, 因为在这个方法之外,根本无法取得Inner Class的任务信息
*/
public Object methodWithInnerClass(){
class Inner{
@Override
public String toString(){
return "this is an Inner class in a method";
}
}
return new Inner();
}
}
匿名式内部类
这种方式经常可以在我们的代码里看到,特别是写事件程序时.
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class AnonymousInnerClassExample {
public static void main(String[] args) {
Frame f = new Frame("Anonymous Inner Class Example");
f.addWindowListener(new WindowAdapter(){
@Override
public void windowClosed(WindowEvent e) {
System.exit(1);
}
});
f.setSize(200, 100);
f.setVisible(true);
}
}
总结
- Inner class 可以访问类成员和对象成员,若要访问方法的变量,则该变量必须为final变量.
- Inner class 可以是一个抽象类
- Inner class 可以是一个接口
- Inner class 可以使用任一个访问权限修饰符
- Inner class 可以使用static修饰符(类成员)
- Inner class 中的成员若要使用static修饰符,则该inner class必须也是static
- Inner class 中若要使用外部类的类成员,则该inner calss必须也是static