您的位置:首页 > 编程语言 > Java开发

thinking in java 学习笔记之 Inner Classes

2005-08-28 11:03 821 查看
1. 基本概念:
    内部类,也叫嵌套类,能使你的程序更清晰和简洁。
    内部类,像其名字一样,是定义在类的内部的。内部类和一般的类基本上是一样的,其复杂性在于它的作用范围和访问性。
    内部类的语法结构如下:
    //---------------------------------------------
    public class OuterOne{
        private int x;
        //inner class
        public class InnerOne{
            private int y;
            public void innerMethod(){
                System.out.println("y is "+ y);
            }
        }
        public void outerMethod(){
            System.out.println("x is "+ x);
        }
        //outer methods...
    }
 //---------------------------------------------
    访问内部类时使用OuterOne.InnerOne。内部类在编译后产生的.class文件名是:OuterOne$InnerOne,用美元符号是用于区别包成员.
2. 在内部类中使用父类的成员:
    内部类中有一个隐藏的引用,指向外部类的实例。所以在内部类中可以直接访问外部类中的成员。例如
     //---------------------------------------------
    public class OuterOne{
        private int x;
        //inner class
        public class InnerOne{
            private int y;
            public void innerMethod(){
                System.out.println("enclosing x  is "+ x);
                System.out.println("y is "+ y);
            }
        }
        public void outerMethod(){
            System.out.println("x is "+ x);
        }
 
        public void makeInner(){
            InnerOne anInner = new Inner();
            anInner.innerMethod();
        }
        //outer methods...
    }
    //---------------------------------------------
3. Member Classes
    (1)Access Modifiers
    一个类的成员,无论是变量、方法,还是嵌套类,都能加以修饰符,用来控制对其的访问。
    内部类如果作为一个类的成员,也能被赋予private,protected,public或者默认访问控制符。
    (2)Static Inner Classes
    像其他类成员一样,一个成员内部类也可以是static。这样,你可以不用创建父类的实例就能创建一个内部类的实例,例如:
    //---------------------------------------------
    public class MyOuter{
        public static class MyInner{

        }
        public static void main(String[] a){
            MyInner aMyInner = new MyOuter.MyInner();
        }
    }
    //----------------------------------------------
4. Classes Defined Inside Methods
    (1)在方法内部定义的内部类不再是类的成员,只是属于该方法的局部成员。所以该内部类只属于此方法,不能加以访问控制符和static修饰符。
    在方法内部定义的内部类能访问该方法中的某些变量,具体规则如下:
    某个方法中的局部变量或者传进来的参数,只要是final类型,都可以被该方法中定义的内部类的方法访问。例如:
   
//-------------------------------------------------------
    public class MOuter{
        private int m = (int)(Math.random()*100);
        public static void main(String[] a){
            MOuter that = new MOuter();
            that.go((int)(Math.random()*100),(int)         (Math.random()*100));
 }
        public void go(int x, final int y){
            int a = x + y;
            final int b =x - y;
            //------Inner Class------------
            class MInner{
              public void method(){
                System.out.println("m is "+m);//内部类中直接访问外部类的成员
               //System.out.println("x is "+x);//Illegal!!
               System.out.println("y is "+y);//y is final
               //System.out.println("a is "+a);//Illegal!!
               System.out.println("b is "+b);//b is final
             }
            }
           //-------Inner Class over--------
           MInner that = new MInner();
           that.mehtod();
       }
    }
    //----------------------------------------------------
    (2)匿名类
    你在定义一个类的时候可以不用去想他该叫什么名字,常用在事件监听机制。
    因为匿名类没有名字,所以不能想平常那样用new关键字去创建匿名类的实例。事实上,匿名类的定义、创建和第一次使用(通常是赋值)都发生在同一个地方。
//-------------------------------------------------------
    public class MOuter{
        private int m = (int)(Math.random()*100);
        public static void main(String[] a){
            MOuter that = new MOuter();
            that.go((int)(Math.random()*100),(int)         (Math.random()*100));
 }
        public void go(int x, final int y){
            int a = x + y;
            final int b =x - y;
            //------Inner Class------------
            class MInner{
              public void method(){
                System.out.println("m is "+m);//内部类中直接访问外部类的成员
               //System.out.println("x is "+x);//Illegal!!
               System.out.println("y is "+y);//y is final
               //System.out.println("a is "+a);//Illegal!!
               System.out.println("b is "+b);//b is final
             }
            }
           //-------Inner Class over--------
           MInner that = new MInner();
           that.mehtod();
       }
    }
    //----------------------------------------------------
    (2)匿名类
    你在定义一个类的时候可以不用去想他该叫什么名字,常用在事件监听机制。
    因为匿名类没有名字,所以不能想平常那样用new关键字去创建匿名类的实例。事实上,匿名类的定义、创建和第一次使用(通常是赋值)都发生在同一个地方。

    内部类能被声明为继承另一个类或仅实现一个的接口。下面这个例子说明怎么创建一个典型的内部类,它实现了一个接口 ActionListener:
   //----------------------------------------------------
    public void aMethod(){
        theButton.addActionListener(
        new ActionListener(){
          public void actionPerformed(ActionEvent e){
            System.out.println("The action has occured.");
          }
       }
       );
    }
    //----------------------------------------------------
    其中,整个内部类的定义构成了addActionListener方法的参数。接口ActionListener直接出现在new 关键字后.
    当编译器遇到匿名类时,为匿名类产生独立的.class文件:EnclosingClassName$n.class,(n是属于EnclosingClass的匿名类的序号,从1开始)
    使用匿名类的两种情况:匿名类返回对象的引用
    1)Xxxx anXxxx = new Xxxx(){/* class body. */};//赋值用
    2)someMethod(new Xxxx(){/* class body. */});//当作参数传递

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息