内部类总结


以下内容均来自:百度文库,略有改动.

1.内部类分类:

/*
内部类分类:
  ①成员内部类:实例内部类和静态内部类
  ②局部内部类
  ③匿名内部类
*/

2.成员内部类(定义在成员位置上)的实例内部类(非静态内部类)

在创建实例内部类的实例的时候,外部类的实例必须已经存在
    
    Outer.InnerTools its = new Out().new InnerTools();
        以上代码等价于:
        Outer out = new Outer();
    Outer.InnerTools its = out.new InnerTools();
   ②  实例内部类的实例【自动】持有对外部类的实例的引用(Outer.this
),所以在实例内部类中 可以直接访问外部类的[所有]成员(这里指的是外部类当中所有的public,protected,private
,static的方法和成员变量)
        (可以理解为就是外部类中的成员与成员之间的访问)
        之所以能访问,是因为在实例内部类中需要 先有外部类的实例,才能有内部类的实例.
        
    Outer.InnerTools its = new Outer().newInnerTools();
③ 在实例内部类中,外部类的实例与内部类的实例是一对多的关系,一个内部类实例
只会引用一个外部类实例,而一个外部类实例对应0个或n个内部类实例(可以有多个内部类)在外部类
中【不能】直接访问内部类的成员,必须通过内部类的实例去访问才可以。
  

class Outer
{   
   
    static int a=10;
   
   
    class Inner
    {
       
        int i=3;
        void method()
        {
          a=7;//可以
        }
    }

}
class Demo
{
    public static  void main(String[] args)
    {
   
      new Outer().new Inner().method();

    }
}

在实例内部类中不能定义静态成员(和静态成员只能访问静态成员一个道理)

3.静态内部类:

(1) 静态内部类的实例【不会自动持有】外部类的实例的引用,在创建内部类的实例时,不必创建外部类的实例
       //示例:
       Class A{
  Public static class B{
           Int v;
      }
}

Class Test{
           Public void test(){
              A.B b = new A.B();
        b.v = 1;
         }
}
  (2) 静态内部类可以直接访问外部类的静态成员如果访问外部类的实例成员,就必须通过外部类的实例去访问

class A 
{
    private int a1;
    private static int a2;

    public static class B
    {
        //int b1 = a1; 错误
        int b2 = a2;//0
        int b3 = new A().a1;//0
    }
}

 

(3
) 在静态内部类中可以定义静态成员和实例成员

class A
{
    public static class B
    {
        int v1;
        static int v2;

        public static class C
        {
            static int v3;
        }
    }
}
(
4
) 外部类可以通过完整的类名来直接访问静态内部类的静态成员

class A
{
    public static class B
    {
        int v1;
        static int v2;

        public static class C
        {
            static int v3;
            int v4;
        };
    };
};

public class Client
{
    public void test(){
        A.B b = new A.B();//内部类B的实例
        A.B.C c = new A.B.C();//内部类C的实例
        b.v1 = 1;//通过实例访问B中非静态v1
        b.v2 = 1;//通过实例访问B中静态v2
        //A.B.v1 = 1//error
        A.B.v2 = 1;
        A.B.C.v3 = 1;
    }
}

4.局部内部类:

局部内部类是在一个方法当中定义的内部类,
它的可见范围是当前方法
和局部变量一样,局部内部类不能使用访问修饰符(public , private , protected) 以及 static
 来修饰,
    
    局部内部类的特点是:


(
1
) 局部内部类只能在当前方法中使用.
    class A
{
    //B b = new B();//error

    public void method(){
        class B
        {
            int v1;
            int v2;

            class C
            {
                int v3;
            };
        };
        B b = new B();
        B.C c = b.new C();
        //可见B和C的作用作用域均在method方法体内
    }
}
(2) 局部内部类和实例内部类一样,不能包含静态成员。
    原因:(反证)如果可以包含
->该内部类必须为static->
而局部内部类不能被成员修饰符修饰
class A
{
    public void method(){
        class B
        {
            //static int v1;//error
            int v2;

            //static class C //error
            {
                int v3;
            }
        }

    }
}

 

(3) 
在局部内部类中定义的内部类同样也不能被public protected, private这些访问修饰符修饰(局部内部类不能被public protected
  private访问修饰符修饰)

(4)  
局部内部类和实例内部类一样,可以访问外部类的所有成员(包括外部类的静态成员:Outer.静态静态成员)
(依然持有外部类引用:Outer.this),此外,
      局部内部类还可以访问所在方法中的final类型的参数和变量(关于这一点我想另写一篇讨论)

class A
{
    int a;
    public void method(final int p1,int p2){
        int localV1 = 1;
        final int localV2 = 2;

        class B
        {
            int b1 = A.this.a;
            int b2 = p1;
            //int b3 = p2;//error 不能访问,p2非finnal
            //int b4 = localV1//error 同理
            int b5 = localV2;
        };
    }
}

5.匿名内部类(匿名子类对象):

(1
) 匿名内部类本身没有构造器(无类名),但是会调用父类中的构造器。(相当于该匿名内部类实现了接口或继承一个类)


public class A {

    A(int y){
        System.out.println("不是默认构造器");
    }
    A(){
        System.out.println("默认构造器");
    }
    
    void method(){
        System.out.println("from A");
    }
    
    public static void main(String[] args) {
        //new A().method();//默认构造器,from A
        A a = new A(){
            void method(){
                System.out.println("我是匿名内部类中的method方法");
            }
        }
        //也就是说匿名构造器会自动调用父类中的构造器
        a.method();//输出结果:默认构造器 我是匿名内部类中的method方法
    }
}
  (
2
) 匿名内部类尽管没有构造方法(因为没有类名),但是可以在匿名内部类中提供一段实例初始化代码(构造代码块),Java虚拟机会在调用了父类的构造方法之后,执行这段代码。

  public static void main(String [] args){
 int v = 1;
 A a = new A(v){
        {
      System.out.println("init instance");
     }
     void method(){
     System.out.println("from anonymous");
    }  
 }
a.method();
}


  程序执行结果如下:
  another constructer//父类当中的构造器执行的结果
  init instance
  from anonymous
 
(
3
) 除了可以在外部类的方法内定义匿名类外,还可以在声明一个成员变量时定义匿名内部类。

   abstract class A{
        
        A a = new A(){
           void method(){
             System.out.println("inner"); 
           }
           //把匿名内部类定义在了成员位置上
     }
     abstract void method(); 
   }

 

(4
)   匿名内部类除了可以继承类外,还可以实现接口【重点】
 
   Class Sample{
   public static void main(String [] args){
      Thread t = new Thread(new Runnable(){
        public void run(){
             for(int i = 0; i < 100; i++){
               System.out.print(i);
            }
    }
      });
   }  
 }
(
5
) 匿名内部类同局部内部类一样,可以访问外部类的所有成员,如果匿名内部类位于一个方法中,还能访问所在方法的final 类型的变量和参数

(6) 局部内部类和匿名内部类一样,名字在方法外都是不可见的,因此都可以起到封装类型名字的作用。
posted @ 2013-04-02 16:44  伊秋  阅读(254)  评论(0编辑  收藏  举报