public class Test {
    public static void main(String[] args) {
//        Parcel4Test.test();
//        Parcel5_1.test();
//        Parcel6.test();
//        Parcel8.test();
//        Parcel9.test();
//        AnonymousConstructor.test();
        Parcel10.test();
    }
}

/*
    当内部类向上转型为其基类,尤其是转型为一个接口时,内部类就有了用武之地。
    (从实现了某个接口的对象,得到对此接口的引用,与向上转型为这个对象的基类
    实质上效果是一样的。)这是因为此内部类——某个接口的实现——能够完全不可
    见,并且不可用。所得到的只是指向基类或者接口的引用,能方便的隐藏实现细节
 */

interface Destination{
    String readLable();
}

interface Content {
    int value();
}

class Parcel4 {
    private class PContents implements Content {
        private int i = 11;
        @Override
        public int value() {
            return i;
        }
    }

    protected class PDestination implements Destination {
        private String label;
        @Override
        public String readLable() {
            return label;
        }

        public PDestination(String label) {
            this.label = label;
        }
    }

    //这个地方就发生了向上转型
    public Destination to(String toWhere) {
        return new PDestination(toWhere);
    }

    //这个地方就发生了向上转型
    public Content contents() {
        return new PContents();
    }
}

/*
    private 内部类给类的设计者提供了一种途径,通过这种方式完全可以阻止任何依赖于类型
    的编码,并且完全隐藏了实现细节。
 */

class Parcel4Test {
    public static void test() {
        Parcel4 p = new Parcel4();
        Content c = p.contents();
        Destination d = p.to("E");

        //无法访问
        //Parcel4.PContents pc = p.new PContents();
    }
}

/*
    定义在方法中的类:
        在destination()中定义了内部类PDestination,并不代表一点destination()方法
        执行完毕了,PDestination就不可用了。

            ——如果,这个内部内访问了方法里的参数的话,会怎样呢?
 */
class Parcel5 {
    public Destination destination(String s) {

        /*
            实验:看是否方法内部的类,能不能访问方法里的数据
            结论:
                可以访问?
                    ——那这个方法消失后,这些数据会怎样呢?
         */

        int h = 100;
        class PDestination implements Destination {
            private String Label;
            private int a;

            public PDestination(String label) {
                a = h;
                Label = label;
            }

            @Override
            public String readLable() {
                return Label;
            }
        }
        return new PDestination("F");
    }

    public static void test() {
        Parcel5 p = new Parcel5();

        Destination d = p.destination("H");
    }
}

/*
    实验:
        1.定义在方法内部的内,能否访问方法里的参数
        2.方法执行完毕后,这个内部内还能访问这些参数么
        3.如果方法里的参数是基本数据类型(储存在栈中),还可以访问么

    结论:
        可以访问哦,这就有点恐怖了!这有点香Lua中的闭包了,我能理解它,但是
        这和我在C++里学的有很大的出入。
 */

class Parcel5_1 {
    public Destination destination(String s) {

        int[] arr = new int[100];
        int a = 10;

        for (int i = 0; i < 100; i++) {
            arr[i] = i;
        }

        class PDestination implements Destination {
            private String Label;
            private int i = 0;

            public PDestination(String label) {
                Label = label;
            }

            @Override
            public String readLable() {
//                return arr[i++]+"";
                return a+"";
            }
        }
        return new PDestination("F");
    }

    public static void test() {
        Parcel5_1 p = new Parcel5_1();

        Destination d = p.destination("H");

//        System.out.println("f:"+d.readLable());
//        System.out.println("s:"+d.readLable());
//        System.out.println("t:"+d.readLable());
        System.out.println("a:"+d.readLable());
        System.out.println("a:"+d.readLable());
        System.out.println("a:"+d.readLable());
    }
}

/*
    定义在作用域的类,此作用域在方法的内部
 */
class Parcel6 {
    private void internalTracking(boolean b){
        if(b){
            class TrackingSlip{
                private String id;

                TrackingSlip(String s) {
                    id = s;
                }
                String getSlip() {
                    return id;
                }
            }
            TrackingSlip ts = new TrackingSlip("slip");
            String s = ts.getSlip();
        }
    }

    public void track() {
        internalTracking(true);
    }

    public static void test() {
        Parcel6 p = new Parcel6();
        p.track();
    }
}

/*
    实现了接口的匿名类
 */
class Parcel7 {
    public Content contents() {
        return new Content() {
            private int i = 11;
            @Override
            public int value() {
                return i;
            }
        };
    }

    public static void test() {
        Parcel7 p = new Parcel7();
        Content c = p.contents();
    }
}

/*
    一个匿名类,它扩展了有非默认构造器的类

    你的基类需要一个有参数的构造器,应该怎么办?
 */
class Wrapping {
    private int i;

    public Wrapping(int x) {
        this.i = x;
    }

    public int value() {
        return i;
    }

}
class Parcel8 {
    public Wrapping wrapping(int x) {
        return new Wrapping(x){
            public int values() {
                return super.value() * 47;
            }
        };
    }

    public static void test() {
        Parcel8 p = new Parcel8();
        Wrapping w = p.wrapping(10);
        System.out.println("w.value():"+w.value());
    }
}

/*
    一个匿名类,它执行字段的初始化

    如果定义一个匿名内部类,并希望它使用一个在外部定义的对象,那么编译器会要求其参数的引用
    是final的,就像你在destination()中看到的那样。
 */
class Parcel9 {
    public Destination destination(final String dest) {
        return new Destination() {
            private String label = dest;
            @Override
            public String readLable() {
                return label;
            }
        };
    }

    //实际上,我没有传入一个final值,编译器没有报任何错误,时代不一样了
    public Destination destination2(String dest) {
        return new Destination() {
            private String label = dest;
            @Override
            public String readLable() {
                return label;
            }
        };
    }

    public static void test() {
        Parcel9 p = new Parcel9();
        Destination d1 = p.destination("CCC");
        Destination d2 = p.destination2("HHH");
        System.out.println("d1:"+d1.readLable());
        System.out.println("d2:"+d2.readLable());
    }
}

/*
    一个匿名类,它通过实例初始化实现构造(匿名类不可能有构造器)

    需求:
        如果想做一些类似的构造器的行为,该怎么办?在匿名类中不可能有命名的构造器
        (因为它根本没有名字!),但通过实例初始化,就能够达到为匿名内部类创造一
        个构造器的效果
 */
abstract class Base {
    public Base(int i) {
        System.out.println("Base constructor i = " + i);
    }

    public abstract void f();
}

class AnonymousConstructor {
    public static Base getBase(int i) {
        return new Base(i) {
            {
                System.out.println("Inside instance initializer.");
            }
            @Override
            public void f() {
                System.out.println("In anonymous f()");
            }
        };
    }

    public static void test() {
        Base base = getBase(47);
        base.f();
    }
}

class Parcel10 {
    public Destination destination(final String dest, final float price) {
        return new Destination() {
            private int cost;
            {
                cost = Math.round(price);
                if (cost > 100) {
                    System.out.println("Over budget!");
                }
            }
            private String label = dest;

            @Override
            public String readLable() {
                return label;
            }
        };
    }

    //测试不用final关键字会怎样
    public Destination destination2(String dest,float price) {
        return new Destination() {
            private int cost;
            {
                cost = Math.round(price);
                if (cost > 100) {
                    System.out.println("Over budget!");
                }
            }
            private String label = dest;

            @Override
            public String readLable() {
                return label;
            }
        };
    }

    public static void test() {
        Parcel10 p = new Parcel10();
        Destination d1 = p.destination("AAA", 10.f);
        Destination d2 = p.destination2("BBB", 11.f);
    }
}

Java编程思想:内部类中级部分的更多相关文章

  1. Java编程思想学习(八) 内部类

    可以将一个类的定义放在另一个类的定义内部,这就是内部类. 内部类的定义是简单的,但是它的语法确实很是复杂,让人不是很好理解.下面就内部类做一个小结. 一.内部类的分类 总的来讲内部类分为普通内部类,匿 ...

  2. Java编程思想重点笔记(Java开发必看)

    Java编程思想重点笔记(Java开发必看)   Java编程思想,Java学习必读经典,不管是初学者还是大牛都值得一读,这里总结书中的重点知识,这些知识不仅经常出现在各大知名公司的笔试面试过程中,而 ...

  3. Java编程思想读书笔记之内部类

    现在是够懒得了,放假的时候就想把这篇笔记写出来,一直拖到现在,最近在读<Java编程思想>,我想会做不止这一篇笔记,因为之前面试的时候总会问道一些内部类的问题,那这本书的笔记就从内部类开始 ...

  4. java编程思想

    Java编程思想,Java学习必读经典,不管是初学者还是大牛都值得一读,这里总结书中的重点知识,这些知识不仅经常出现在各大知名公司的笔试面试过程中,而且在大型项目开发中也是常用的知识,既有简单的概念理 ...

  5. Java编程思想 (1~10)

    [注:此博客旨在从<Java编程思想>这本书的目录结构上来检验自己的Java基础知识,只为笔记之用] 第一章 对象导论 1.万物皆对象2.程序就是对象的集合3.每个对象都是由其它对象所构成 ...

  6. Java 编程思想 Chapter_14 类型信息

    本章内容绕不开一个名词:RTTI(Run-time Type Identification) 运行时期的类型识别 知乎上有人推断作者是从C++中引入这个概念的,反正也无所谓,理解并能串联本章知识才是最 ...

  7. Java编程思想(前十章)

    Java编程思想 有C++编程基础的条件下, 前10章可以快速过一下,都是基本语法,不需要花太多时间. 着重中后段的一些章节,类型信息.泛型.容器.IO.并发等. 中文翻译版 阅读地址 对于一个架构师 ...

  8. 《Java编程思想第四版完整中文高清版.pdf》-笔记

    D.2.1 安插自己的测试代码 插入下述“显式”计时代码,对程序进行评测: long start = System.currentTimeMillis(); // 要计时的运算代码放在这儿 long ...

  9. 《Java编程思想第四版》附录 B 对比 C++和 Java

    <Java编程思想第四版完整中文高清版.pdf>-笔记 附录 B 对比 C++和 Java “作为一名 C++程序员,我们早已掌握了面向对象程序设计的基本概念,而且 Java 的语法无疑是 ...

  10. Java编程思想中关于闭包的一个例子

    Java编程思想中的一个例子,不是很理解使用闭包的必要性,如果不使用闭包,是不是有些任务就不能完成?继续探索. package InnerClass; interface Incrementable ...

随机推荐

  1. Qt for windows消息循环、libqxt分析和wince快捷键处理

    Qt for windows消息循环.libqxt分析和wince快捷键处理 利用Qt做windows图形界面开发和MFC相比,个人感觉还是比较简单好用的:首先利用Designer工具搞个ui文件:然 ...

  2. Visual Studio 2017报表RDLC设计器与工具箱中Report Viewer问题

    原文:VS2017入门 RDLC入门之01 本系列所有内容为网络收集转载,版权为原作者所有. VS2017初始安装后和VS2015一样,都没有ReportDesigner/ReportViewer R ...

  3. C# 利用 OpenCV 进行视频捕获 (笔记)

    原文:C# 利用 OpenCV 进行视频捕获 (笔记) 简介 这个项目是关于如何从网络摄像头或者视频文件(*.AVI)中捕获视频的,这个项目是用C#和OPENCV编写的. 这将有助于那些喜欢C#和Op ...

  4. C#图片旋转

    这里以Bitmap为例说明问题. 可以看到,旋转方法需要传入一个参数,而这个参数是一个枚举类型,RotateFlipType. 系统提供了两大类型的旋转, 1.旋转后不翻转. 2.旋转后接着翻转.翻转 ...

  5. UAP开发错误之The given System.Uri cannot be converted into a Windows.Foundation.Uri(windows phone背景更换)

    今天博主在开发一款windows phone应用时,希望实现app背景的更换,思路很简单.使用ApplicationDataContainer容器存储我的图片路径,每次载入应用时读取这个路径以决定我用 ...

  6. QML动画概述(几十篇相关博客)

    QML提供了丰富的动画元素,说起动画,无非是给UI增光添彩罢了.在QML中,动画常常与State和Transition联系在一起,这几个概念(下面的例子中都用到了)都比较简单,相关介绍可查看Qt官方文 ...

  7. .NET错误:未找到类型或命名空间名称

    现象:编译项目时提示未找到类型或命名空间名称"... " 解决方法:如果是未找到类型,检查是否引用了类型所在的命名空间,使用using指令:如果是未找到命名空间,那么检查是否引用了 ...

  8. 3014C语言_运算符

    第四章 运算符 4.1 分类 C语言的运算符范围很广,可分为以下几类: 1.算术运算符:用于各类数值运算.包括加(+).减(-).乘(*).除(/).求余(%).自增(++).自减(--)共七种. 2 ...

  9. Zookeeper详解-概述(一)

    ZooKeeper是一种分布式协调服务,用于管理大型主机.在分布式环境中协调和管理服务是一个复杂的过程.ZooKeeper通过其简单的架构和API解决了这个问题.ZooKeeper允许开发人员专注于核 ...

  10. 使用ln -s解决库冲突的问题

    1. linux系统下软连接ln -s的使用方法: 软连建立:ln  -s  源文件 软链接文件 对源文件创建软连接文件,举例说明 举例: 当前目录是/local,而我经常要访问/usr/local/ ...