2018.10.12学习笔记

10.12学习笔记

今天学习了《Java编程思想》的第十章—内部类的后半部分。下面对今日收获与疑惑作一个总结。


1.匿名内部类:
返回值的生成与表示这个返回值的类的定义结合在一起。另外,这个类是匿名的,他没有名字。
①由于匿名内部类没有名字,所以使用构造代码块来代替构造函数

public abstract class Base {
    public Base(int i){
        System.out.println("Base constructor, i = " + i);
    }

    public abstract void test();
}


public class AnonymousBase {
    public Base getBase(int i){
        return new Base(5){
            {System.out.println("AnonymousBase initializer");}//构造代码块充当了构造函数的功能
            @Override
            public void test() {
                System.out.println("fuQian");
            }
        };
    }

    public static void main(String args[]){
        AnonymousBase anonymousBase = new AnonymousBase();
        anonymousBase.getBase(5).test();
    }
}

但是它收到了限制,不能重载实例初始化方法

2.构造代码块:
构造代码块在类中用{}定义,作用是给对象进行初始化。构造代码块与构造函数的区别是:构造代码块是给所有的对象进行统一初始化,而构造函数是给对应的对象进行初始化

①静态代码块与非静态代码块:
非静态代码块无论建立哪个对象,都会先执行相同的代码块—构造代码块中定义的是不同对象共性的初始化内容。静态代码块,它是随着类的加载而执行,只执行一次。但无论是静态代码块还是非静态代码块,都会在构造方法调用之前被加载

②初始化顺序:
先加载静态的,即静态构造块(类静态属性),然后才是非静态的构造块(非静态属性),最后才是调用类构造方法。注意静态的,即静态构造块和静态属性不分先后,按在类定义的先后顺序进行初始化

3.嵌套类(静态内部类):
接口中的内部类:
嵌套类可以作为接口的一部分,因为类是static的,所以不违反接口的规则。放在接口中的任何类都自动地是public和static的,你甚至可以在内部类中实现其外围接口

public interface ClassInInterface {
    void howdy();

    class Test implements ClassInInterface{
        @Override
        public void howdy(){
            System.out.println("接口的嵌套类");
        }
        static class Tester{
            public static void main(String args[]){
                Test test = new Test();
                test.howdy();
            }
        }
    }
}

4.为什么需要内部类:
每个内部类都能独立地实现一个接口或者继承具体、抽象的类(相当于实现了多重继承),或者可以让多个类以不同的方式实现同一个接口或继承自同一个类

public interface Selector {
    boolean end();
    Object current();
    void next();
}


/*
description:在同一个类中,创建两个内部类实现了Selector接口的不同实现,从而实现了向前和向后进行遍历
 */
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;

        @Override
        public boolean end(){
            return i == items.length;
        }

        @Override
        public Object current(){
            return items[i];
        }

        @Override
        public void next(){
            if (i=0)
                i--;
        }
    }

    public Selector selector(){
        return new SequenceSelector();
    }

    public Selector selector_reverse(){
        return new SequenceSelector_reverse();
    }

    public static class Tester{
        public static void main(String args[]){
            Sequence sequence = new Sequence(10);
            Sequence sequence_reverse = new Sequence(10);
            for (int i = 0;i< sequence.items.length;i++){
                sequence.add(i);
                sequence_reverse.add(i);
            }
            Selector selector = sequence.new SequenceSelector();
            Selector selector_reverse = sequence.new SequenceSelector_reverse();

            while (!selector.end()){
                System.out.print(selector.current() + " ");
                selector.next();
            }

            while(!selector_reverse.end()){
                System.out.print(selector_reverse.current() + " ");
                selector_reverse.next();
            }
        }
    }
}/*output
0 1 2 3 4 5 6 7 8 9 9 8 7 6 5 4 3 2 1 0
*/

5.内部类的继承:
因为内部类的构造器必须连接到指向其外部类对象的引用,所以,那个指向外部类对象的引用必须被初始化

public class FirstOuter {
    class FirstInner{
        public FirstInner(int i){
            System.out.println("第一个内部类" + i);
        }
    }
}


public class SecondOuter {
    class SecondInner extends FirstOuter.FirstInner{
        SecondInner(FirstOuter firstOuter,int i){ //外部类对象的引用以及传入的参数
            firstOuter.super(i);
        }
    }
}

你可能感兴趣的:(学习笔记)