java 内部类

/**个人理解,如果发现有不当之处,还请谅解并告知*/

将一个类的定义放在另一个类的定义内部,就是内部类。内部类一般分以下几种

1.普通内部类

1)

public class OuterClass {

    class Inner{
        private String name;
        Inner(String input){
            this.name = input;
        }
    }

    public static void main(String[] args) {
        OuterClass outerClass = new OuterClass();
        Inner inner = outerClass.new Inner("this is inner");
        System.err.println(inner.name);
    }
}
View Code

 

注:创建内部类对象的方法是使用   ".new" 来进行,在拥有一个外部类对象之前,是不能创建内部类 对象的 。

内部类主要用以隐藏名字和组织代码,此外,当用OuterClass创建Inner对象时,该对象会隐秘的获取一个指向OuterClass的引用,因此,创建的内部类对象会自动拥有外部类所有成员的访问权。

2)常用于隐藏实现

public class OuterClass {

    public SuperInterface superInterface(String words) {
        class Inner implements SuperInterface {
            private String greeting;

            private Inner(String outerGreeting){
                this.greeting = outerGreeting;
            }
            @Override
            public String sayHello() {
                return greeting;
            }
        }
        return new Inner(words);
    }


    public static void main(String[] args) {
        OuterClass outerClass = new OuterClass();
        SuperInterface superInterface = outerClass.superInterface("Here you are");
        System.err.println(superInterface.sayHello());
    }
}

interface SuperInterface{
    String sayHello();
}
View Code

 

2.匿名内部类

public class OuterClass {

    public SuperInterface superInterface(String words){
        return new SuperInterface(){
            private String greeting = words;

            @Override
            public String sayHello() {
                System.err.println("inner"+greeting);
                return greeting;
            }
        };
    }

    public static void main(String[] args) {
        OuterClass outerClass = new OuterClass();
        SuperInterface superInterface = outerClass.superInterface("Hello");
        System.err.println(superInterface.sayHello());

    }
}

interface SuperInterface {
    String sayHello();
}
View Code

匿名内部类是指创建一个继承/实现自另一个外部类的匿名对象,并通过向上转型返回一个对外部类的引用,如上面代码所示,通过new生成一个实现了SuperInterface的匿名类对象的引用,然后自动向上转型为指向SuperInterface的引用。

注:java8之前,如果匿名内部类需要使用一个外部定义的对象(如上面代码中的入参words),会要求参数必须为final类型的,java8之后,会自动的声明为隐式的final类型。

 3.嵌套类

嵌套类又称为静态内部类,和普通内部类不同的是,嵌套类不需要内部类对象与其外围对象有联系,只需要将类声明为static。

1)创建嵌套类对象并不需要其外部对象

2)不能从嵌套类对象访问非静态外部类对象

3)嵌套类可以作为接口的一部分

public interface ClassInterface {

    void sayHello();

    class ClassImpl implements ClassInterface{

        @Override
        public void sayHello() {
            System.err.println("Hello");
        }

        public static void main(String[] args) {
            new ClassImpl().sayHello();
        }
    }
}
View Code

 

由于匿名内部类允许继承多个非接口类型(抽象类,类),使得 多重继承 得以实现。

和内部类相关的其他概念:

1.闭包(Closure)

闭包又叫词法闭包(Lexical Closure)或函数闭包(Function Closure)

概念一:闭包就是能够读取其他函数内部变量的函数;

概念二:闭包是引用了自由变量的函数;

因此,Java中的内部类就可以看做是一个闭包,因为内部类能够访问外部类的所有变量(相当于自由变量);

java中常用的迭代器模式就是应用内部类来实现的,例:

public class Sequence {
    /**
     * 保存数据
     */
    private Object[] items;

    private int next = 0;

    /**
     * 初始化数组
     */
    public Sequence(int size) {
        items = new Object[size];
    }

    /**
     * 添加数据
     */
    public void add(Object data){
       if(next<items.length){
           items[next++] = data;
       }
    }
    private class SequenceSelector implements Selector {
        private int i;
        /**
         * 如果不在末尾,计数器加1
         */
        @Override
        public void next() {
            if (i < items.length) {
                i++;
            }
        }
        /**
         * 是否在末尾
         */
        @Override
        public boolean end() {
            return i == items.length;
        }
        /**
         * 返回当前对象
         */
        @Override
        public Object current() {
            return items[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 = sequence.selector();
        while (!selector.end()){
            System.err.print(selector.current()+",");
            selector.next();
        }
    }
}

interface Selector {
    void next();

    boolean end();

    Object current();


}
View Code

 

 

ps小王知识点:过了很久终于我愿抬头看,你就对面敲打键盘

posted @ 2018-07-24 23:45  NealRiver  阅读(151)  评论(0编辑  收藏  举报