作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!

到现在为止,我们都是在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快速教程”系列文章

转载于:https://www.cnblogs.com/vamei/archive/2013/04/16/3000896.html

Java进阶07 嵌套类相关推荐

  1. 【Java 进阶】匿名类(代码传递、回调、过滤器)、Lambda表达式(方法引用)、函数式接口(Supplier、Consumer、Predicate、Function)

    匿名类 匿名类(Anonymous Class) 匿名类的使用注意 匿名类 - 代码传递 - 测试代码运行时间的工具类 匿名类 - 回调 - 简易网络请求 匿名类 - 过滤器 - 获取目录下的所有文件 ...

  2. Java进阶:File类

    概述 在以往的程序设计中,所有的数据在程序运行时都放在内存(RAM)中,而RAM中的数据会随着程序结束或者由于意外断电而消失.现实生活中所有数据最终会保存到硬盘或者闪存盘(ROM)中,然而,计算机只识 ...

  3. java进阶之UML类图和时序图

    目录 UML概述 UML图分类 类图和时序图 类图 类图概述 类图的结构 类图中的关系 时序图 时序图概述 组成元素 示例图 UML概述 统一建模语言(英语:Unified Modeling Lang ...

  4. Java嵌套类(Nested Classes)总结

    Nested Classes定义 在java语言规范里面,嵌套类(Nested Classes)定义是: A nested class is any class whose declaration o ...

  5. 【Java 面向对象】基础、Java程序的内存划分、嵌套类(内部类、静态嵌套类)、局部类、接口的升级问题(默认方法、静态方法)、instanceof

    面向对象 对象的内存 复杂对象的内存 对象数组的内存 思考:方法存储在哪里? Java程序的内存划分 this.super 注解(Annotation) 访问控制(Access Control) to ...

  6. java 嵌套类 继承_Java嵌套类 - 爱吃苹果的搬运工的个人空间 - OSCHINA - 中文开源技术交流社区...

    在Java中可以创建几种不同类型的嵌套类: 静态嵌套类: 静态内部类可以独立于外部类被实例化,无法访问外部类中的非静态属性和方法,只能外部类的实例来访问外部类的非静态变量 public class O ...

  7. 【java开发系列】—— 嵌套类与内部类

    嵌套类与内部类在java中使用的很广泛,为了避免难以理解,这里用了几个小例子,说明它的用法. 嵌套类与内部类的结构如下图 静态嵌套类 静态嵌套类,是一种在类之外声明的嵌套类,由于是静态的,所以不经过初 ...

  8. java 嵌套类 作用_java 嵌套类的分类、为什么使用嵌套类?

    java程序语言允许你在一个类里面再声明另一个类,这样的类成为嵌套类,说明如下:class OuterClass { ... class NestedClass { ... } } 术语:嵌套类分为两 ...

  9. java嵌套类与内部类

    一.嵌套类(Nested Classes) 使用嵌套类减少了命名冲突,一个内部类可以定义在一个类中,一个方法中甚至一个表达式中. (1)定义 A nested(嵌套) class is any cla ...

最新文章

  1. 让瘫痪失语患者「说话」,脑机接口首次从大脑活动解码完整句子,登上新英格兰医学杂志...
  2. Git-TortoiseGit完整配置流程
  3. linux下cmake-gui的安装
  4. 【Android游戏开发之八】游戏中添加音频-详解MediaPlayer与SoundPool的利弊以及各个在游戏中的用途!...
  5. 数据结构---二叉平衡排序树的删除
  6. xp电脑怎么进入bios
  7. 在html中怎么写加起来的,css可以在html里面写吗?
  8. SpringBoot2.0.3 + SpringSecurity5.0.6 + vue 前后端分离认证授权
  9. .net backend return json string , used by frontend
  10. 『转』陆涛为什么不爱米莱
  11. Linux的chkconfig命令详解
  12. 群体智能优化算法之蝙蝠算法(Bat Algorithm,BA)
  13. HID、SCSI、CCID设备的通信
  14. 【时间序列】时间序列数据的缺失填补方法总结
  15. 软件工程之概要设计说明书
  16. 任务的紧急度,重要性划分 .
  17. 电脑“减负”必备,分享一款优秀的重复文件查找工具
  18. CRYPTO buuctf 摩斯
  19. 面试后HR让你等通知的真相
  20. ubuntu下python安装wx包出错解决办法

热门文章

  1. Python基础之函数
  2. 分享自己作为一个程序员的找工作经历
  3. unity3d由多个部分组成一个角色
  4. 不是每个人都可以坚持!
  5. geoserver native JAI error 问题解决方法
  6. GridView强制不换行
  7. 该文件可能是只读的 或者您要访问的位置_喔噢小贴士:如何保护PPT不被更改,将其设为只读...
  8. Netcdf对数据进行裁剪
  9. 软件测试是找BUG,不是找茬
  10. linux命令行sip电话,基于Linux和MiniGUI的SIP电话终端设计