java内部类学习笔记

来源:互联网 发布:focusky下载mac版 编辑:程序博客网 时间:2024/06/05 08:53
java内部类定义:在一个类的内部定义另一个类

实现原理:当我们在一个类outter(这里称作外部类)中定义另外一个类inner(这里称作内部类)时,这个内部类实际上捕获了一个指向外部类成员的引用,换句话讲,内部类中的方法成员可以自由访问外部类中的属性成员,但是注意,只能访问其中的构造器方法,而不能访问其余方法。

下面将以具体的代码讲述其中的知识点,在每条语句的后面都会附上这么写的原因或者实现机制

第一部分:普通内部类

实例一:使用外部类名.内部类名的格式声明一个内部类

public class Demo1 {    /**     * 这里定义一个内部类,这个内部类可以访问包含他的外部类的所有的变量和方法     * 但是外部类却不能访问内部类中被定义为private的成员     */    class Contents{  //这里定义第一个内部类        private int i=11;        public int value(){            return i;        }            }        /**     *     * 如果你不特意指定内部类的成员的访问权限,那么他默认为public的,换句话讲,只要可以找到一个外部类的引用         * 他就可以被同一个包中的所有成员访问     */    class Destination{   //这里定义第二个内部类         private String label;                 Destination(String whereTo){             label=whereTo;         }        String readLabel(){            return label;        }    }        public void ship(String dest){        /*Contents 是一个内部类,但是这里可以直接使用Contents进行声明,是因为内部类同这个         * 方法是同级的,换句话讲,因为内部类在这个方法之前编译,所以当我们的虚拟机在编译这个方法之时,可以“知道”这个类是什么,从而                 *成功编译。        */        Contents c=new Contents();        Destination d=new Destination(dest);        System.out.println(d.readLabel());    }                           public static void main(String args[]){            /**         * 当我们新建一个指向外部类的引用时,其中包含的成员(包括内部类)就已经被编译了         */        Demo1 demo1=new Demo1();        demo1.ship("hello world");                /**                *这个方法是static的。所以编译器先编译它,但这时,编译器还没有编译内部类,所以需要手动地“告诉”编译器这是一个内部类,                *故采用outterclassname.innerclassname的形式进行声明,等号右边要新建一个内部类,此时需要一个外部类的引用                */        Demo1.Contents t=demo1.new Contents();    }    }

实例二:使用接口名声明一个内部类

//这里声明一个接口public interface Selector {boolean end();Object current();void next();}

//当我们的内部类继承自外部的一些接口时,在static方法中声明这些内部类时,可以直接使用使用"接口名"的形式//而不需要使用“外部类名.内部类名”的形式public class Sequence {private Object[] items;private int next=0;public Sequence(int size){items=new Object[size];}public void add(Object x){if(next<items.length){items[next++]=x;}}private class SequenceSelector implements Selector{private int i=0;/**如果没有到达数组的末尾,就返回true,如果没有到达数组的末尾,就返回false * @Override */public boolean end() {// TODO Auto-generated method stubreturn i==items.length;}@Overridepublic Object current() {// TODO Auto-generated method stubreturn items[i];}@Overridepublic void next() {// TODO Auto-generated method stubif(i<items.length){i++;}}}public Selector selector(){return new SequenceSelector();}public static void main(String args[]){Sequence sequence=new Sequence(10);for(int i=0;i<10;i++){sequence.add(Integer.toString(i));}/** * 这里的Selector既是一个内部类,又是一个接口,所以当编译器编译到这条语句时,已经“知道”Selector接口是什么了。                 *换句话讲,可以直接用接口名进行声明,而不用 * outername.innername的形式 */Selector selector=sequence.selector();}}

下面还有匿名内部类的用法,将在后来更新





原创粉丝点击