(十四)内部类

特点

内部类可以访问外部类的所有作用域。

内部类可以对同一个包的其他类隐藏起来。

链接到外部类

当外部类的对象创建一个内部类对象时,此内部类对象必定会捕捉一个指向外部类对象的引用。

内部类的对象只能在与外部类的对象相关联的情况下才能被创建(内部类是非static时),即必须存在外部类的对象。

在外部类的非静态方法以外的地方,需要用Outer.Inner类指明对象类型。

在外部类的非静态方法内,直接用Inner类指明对象类型。

在外部类的静态方法内和其他类中,必须先实例化一个外部类对象,然后使用Outer.Inner in = out.new Inner();类似的格式才能实例化一个内部类对象。

如果内部类是嵌套类(static类),则不需要对外部类的对象的引用,即不需要先实例化外部类对象。

public class Outer {

    public static void main(String[] args) {
        Outer out = new Outer();
        //静态方法里必须先实例化外部类对象,才能利用该对象创建对应的内部类对象
        Outer.Inner in = out.new Inner(1,2);
        out.print();
        in.print();
    }
    //外部类非静态方法中直接Inner in = new Inner()就可以实例化内部类对象
    //外部类非静态方法以外的地方,使用Outer.Inner in = new Outer.Inner();
    public void print(){
        System.out.println("this is outer class!");
        Outer.Inner in = new Outer.Inner(3,4);
        in.print();
    }
    //返回一个指向内部类对象的引用
    public Inner getInner(int i1,int i2){
        return new Inner(i1,i2);
    }
    private class Inner{
        int i1,i2;
        public Inner(int i1,int i2){
            this.i1=i1;
            this.i2=i2;
        }
        public void print(){
            System.out.println("this is inner class!"+"i1="+i1+",i2="+i2);
        }
    }

}

当内部类是private时,在其他类中通过out.new Inner()也无法创建内部类的对象。如下:

 

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Outer out = new Outer();
     //当Inner是private内部类,则下句无法执行
        Outer.Inner in = out.new Inner(2,4);
    }

}

 

局部类

在方法中定义的类,不能设置为public或private,因为该类对方法以外的范围完全是隐藏的。局部类可以访问它的外部类的作用域。

 

匿名内部类

只要一个类是抽象的或是一个接口,那么其子类中的方法都可以使用匿名内部类来实现

抽象类的方法实现

abstract class Person {
    public abstract void eat();
}
 
public class Demo {
    public static void main(String[] args) {
        Person p = new Person() {
            public void eat() {
                System.out.println("eat something");
            }
        };
        p.eat();
    }
}

在接口上使用匿名内部类

interface Person {
    public void eat();
}
 
public class Demo {
    public static void main(String[] args) {
        Person p = new Person() {
            public void eat() {
                System.out.println("eat something");
            }
        };
        p.eat();
    }
}

由上面的例子可以看出,只要一个类是抽象的或是一个接口,那么其子类中的方法都可以使用匿名内部类来实现

最常用的情况就是在多线程的实现上,因为要实现多线程必须继承Thread类或是继承Runnable接口

Thread类的匿名内部类实现

public class Demo {
    public static void main(String[] args) {
        Thread t = new Thread() {
            public void run() {
                for (int i = 1; i <= 5; i++) {
                    System.out.print(i + " ");
                }
            }
        };
        t.start();
    }
}

Runnable接口的匿名内部类实现

public class Demo {
    public static void main(String[] args) {
        Runnable r = new Runnable() {
            public void run() {
                for (int i = 1; i <= 5; i++) {
                    System.out.print(i + " ");
                }
            }
        };
        Thread t = new Thread(r);
        t.start();
    }
}

静态内部类

非静态内部类是附属在外部类对象上的,需要先实例化一个外部类的对象,通过外部类对象才能实例化非静态内部类;而静态内部类可以看做是直接附属在外部类上的,这个静态代表附属体是外部类,而不是外部类实例;

public class Outer {
    int i;
    public static void main(String[] args) {
        Inner in = new Inner();
    }
    public static class Inner{
        public Inner(){
            System.out.println("Inner has been instanced!");
        }
    }

}

 

posted @ 2016-10-17 20:12  且听风吟-wuchao  阅读(242)  评论(0编辑  收藏  举报