Java进阶07 嵌套类
到现在为止,我们都是在Java文件中直接定义类。这样的类出现在包(package)的级别上。Java允许类的嵌套定义。
这里将讲解如何在一个类中嵌套定义另一个类。
嵌套
内部类
Java允许我们在类的内部定义一个类。如果这个类是没有static修饰符,那么这样一个嵌套在内部的类称为内部类(inner class)。
内部类被认为是外部对象的一个成员。在定义内部类时,我们同样有访问权限控制(public, private, protected)。
在使用内部类时,我们要先创建外部对象。由于内部类是外部对象的一个成员,我们可以在对象的内部自由使用内部类:
- public class Test
- {
- public static void main(String[] args)
- {
- Human me = new Human("Vamei");
- me.drinkWater(0.3);
- }
- }
- class Human
- {
- /**
- * inner class
- */
- private class Cup
- {
- public void useCup(double w)
- {
- this.water = this.water - w;
- }
- public double getWater()
- {
- return this.water;
- }
- private double water = 1.0;
- }
- /**
- * constructor
- */
- public Human(String n)
- {
- this.myCup = new Cup();
- this.name = n;
- }
- public void drinkWater(double w)
- {
- myCup.useCup(w);
- System.out.println(myCup.getWater());
- }
- private Cup myCup;
- private String name;
- }
上面的例子中,Cup类为内部类。该内部类有private的访问权限,因此只能在Human内部使用。这样,Cup类就成为一个被Human类专用的类。
如果我们使用其他访问权限,内部类也能从外部访问,比如:
- public class Test
- {
- public static void main(String[] args)
- {
- Human me = new Human("Vamei");
- me.drinkWater(0.3);
- Human.Cup soloCup = me.new Cup(); // be careful here
- }
- }
- class Human
- {
- /**
- * inner class
- */
- class Cup
- {
- public void useCup(double w)
- {
- this.water = this.water - w;
- }
- public double getWater()
- {
- return this.water;
- }
- private double water = 1.0;
- }
- /**
- * constructor
- */
- public Human(String n)
- {
- this.myCup = new Cup();
- this.name = n;
- }
- public void drinkWater(double w)
- {
- myCup.useCup(w);
- System.out.println(myCup.getWater());
- }
- private Cup myCup;
- private String name;
- }
这里,内部类为默认访问权限(包访问权限)。我们可以在Test类中访问Human的内部类Cup,并使用该内部类创建对象。注意我们创建时如何说明类型以及使用new:
Human.Cup soloCup = me.new Cup();
我们在创建内部类对象时,必须基于一个外部类对象(me),并通过该外部类对象来创建Cup对象(me.new)。我将在下一节讲述其中的含义。
闭包
可以看到,我们直接创建内部类对象时,必须是基于一个外部类对象。也就是说,内部类对象必须依附于某个外部类对象。
内部对象与外部对象
与此同时,内部类对象可以访问它所依附的外部类对象的成员(即使是private的成员)。从另一个角度来说,内部类对象附带有创建时的环境信息,也就是其他语言中的闭包(closure)特性。可参考Python闭包
我们看下面的例子:
- public class Test
- {
- public static void main(String[] args)
- {
- Human me = new Human("Vamei");
- Human him = new Human("Jerry");
- Human.Cup myFirstCup = me.new Cup();
- Human.Cup mySecondCup = me.new Cup();
- Human.Cup hisCup = him.new Cup();
- System.out.println(myFirstCup.whosCup());
- System.out.println(mySecondCup.whosCup());
- System.out.println(hisCup.whosCup());
- }
- }
- class Human
- {
- /**
- * inner class
- */
- class Cup
- {
- public String whosCup()
- {
- return name; // access outer field
- }
- }
- /**
- * constructor
- */
- public Human(String n)
- {
- this.name = n;
- }
- public void changeName(String n)
- {
- this.name = n;
- }
- private String name;
- }
运行结果:
Vamei
Vamei
Jerry
在上面的例子中,我们通过内部类对象访问外部类对象的name成员。当我们基于不同的外部对象创建内部类对象时,所获得的环境信息也将随之变化。
嵌套static类
我们可以在类的内部定义static类。这样的类称为嵌套static类(nested static class)。
我们可以直接创建嵌套static类的对象,而不需要依附于外部类的某个对象。相应的,嵌套static类也无法调用外部对象的方法,也无法读取或修改外部对象的数据。从效果上看,嵌套static类拓展了类的命名空间(name space),比如下面的Human.Mongolian:
- public class Test
- {
- public static void main(String[] args)
- {
- Human.Mongolian him = new Human.Mongolian();
- him.Shout();
- }
- }
- class Human
- {
- /**
- * nested class
- */
- static class Mongolian
- {
- public void Shout()
- {
- System.out.println("Oh...Ho...");
- }
- }
- }
在定义嵌套static类时,我们同样可以有不同的访问权限修饰符。
总结
嵌套类允许我们更好的组织类
内部类实现了闭包
Java进阶07 嵌套类的更多相关文章
- Java进阶01 String类
链接地址:http://www.cnblogs.com/vamei/archive/2013/04/08/3000914.html 作者:Vamei 出处:http://www.cnblogs.com ...
- Java中的嵌套类和内部类
以前看<Java编程思想>的时候,看到过嵌套类跟内部类的区别,不过后来就把它们的概念给忘了吧.昨天在看<数据结构与算法分析(Java语言版)>的时候,又遇到了这个概念,当时就很 ...
- Java学习笔记-嵌套类
嵌套类 嵌套类有两种类别:static and non-static,分别对应为静态嵌套类和内部类. class OuterClass { ... static class StaticNestedC ...
- java#内部类和嵌套类
内容思路来自Java编程思想,个人读书做的笔记,仅个人复习之用,故他人参考请自行辨别内容是否有错误. 在类的类部可以定义类,叫做内部类.如果这个内部类被static修饰,此时内部的类叫做嵌套类. 内部 ...
- EffectiveJava(22)JAVA四种嵌套类的特点及用法
嵌套类: 1.静态成员类 静态成员类是外围类的一个静态成员,遵守同样的可访问性规则 用法:a.作为公有的辅助类 内部类: 2.非静态成员类 语法上只和静态成员类的唯一区别是少一个static修饰符 a ...
- Java进阶01 String类(转载)
String类包含在java.lang包中.这个包会在Java启动的时候自动import,所以可以当做一个内置类(built-in class).我们不需要显式的使用import引入String类. ...
- java进阶(8)--匿名类
一.概念 1.内部类:类的内部定义了一个类 2.内部类分类:静态内部类.实例内部类.局部内部类 3.缺点:内部类的可读性比较差,尽量不用 2.匿名内部类:局部内部类的一种 二.匿名内部类的缺点 1 ...
- spring 笔记1: mvn 中Controller方法的参数不能是嵌套类(内部类)。
最近做spring开发,个人认为,Controller和客户端js通讯时传递的参数类 只使用某几个方法,为了减少对其他功能的影响,想把参数类定义为Controller类的 嵌套类(内部类).但是实践发 ...
- JAVA 嵌套类和内部类
一.什么是嵌套类及内部类? 可以在一个类的内部定义另一个类,这种类称为嵌套类(nested classes),它有两种类型: 静态嵌套类和非静态嵌套类.静态嵌套类使用很少,最重要的是非静态嵌套类, ...
随机推荐
- 本地虚拟机LNMP环境安装
首先上传源码包到linux中(本人上传到根目录中),随意上传能找到即可 一.配置YUM源(如果已经配好就不许要重新配置) 挂载光驱要挂载到/mnt下 Mount /dev/cdrom /mnt ...
- getMeasuredHeight(),getScrollY(),getHeight()的区别和联系
前言:关于控件的高度有两种获取方式,一个是获得控件的实际大小(getMeasuredHeight),就是包含显示部分和已显示的部分: 而getHeight是获得控件的显示的大小,如果控件大小超出的屏幕 ...
- smarty模板 变量 运算符 表达式 流程控制 函数
① 从配置文件中读取配置: 1,在模板页面加载配置文件 html页面 不是php页面<{config_load file='fo.conf'}> 2,在需要用到配置的地方加<{#si ...
- iOS系统层次架构
本文转自:http://blog.csdn.net/lxl_815520/article/details/51172917 一,概述 iOS的系统架构分为四个层次:核心操作系统层(Core OS la ...
- Linux学习路线指南
转载的,感觉写的挺好的,我自己知识复制了下,忘记了转载地址,抱歉! Linux学习路线指南 很多同学接触Linux不多,对Linux平台的开发更是一无所知.而现在的趋势越来越表明,作为一个优秀的软件开 ...
- ElasticSearch(十八)初识分词器
1.什么是分词器 作用:切分词语,normalization(提升recall召回率),如给你一段句子,然后将这段句子拆分成一个一个的单个的单词,同时对每个单词进行normalization(时态转换 ...
- NOIP考前划水
NOIP考前划水 君指先跃动の光は.私の一生不変の信仰に.唯私の超電磁砲永世生き! 要开始背配置了? 3行不谢. (setq c-default-style "awk") (glo ...
- 我的Android进阶之旅------>Android关于Log的一个简单封装
android.util.Log类,可以方便地用于在编码调试过程中打印日志.但是在发布后的产品中,如果有太多的日志打印,则会严重地影响性能.对android.util.Log类做一个简单的封装,当产品 ...
- Java mail 发送邮件 主题(标题)乱码
最近开发遇到Javamail 发送邮件标题乱码问题,腾讯.网易邮箱不会乱码,阿里邮箱 标题则会乱码.解决办法: String subject = MimeUtility.encodeWord(ma ...
- json遍历
$.each(item.attributes,function (name,value) { });