深入理解Java内部类
2016-01-26 10:23
274 查看
在讲之前,我们先来思考几个问题
我们先来看一下什么是内部类:可以将一个类的定义放在另一个类的定义内部,这就是内部类。内部类大概分为下面四种:
成员内部类(也叫非静态内部类)
是最普通的内部类,和成员变量和成员方法属于同一层级,可以访问外部类中的所有方法和字段属性。需要注意的是当内部类中的方法或者字段重名是,使用this和父类命进行区分。
局部内部类
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。当访问局部变量是需要添加final关键字,具体原因在我的另外一篇博客四道Java基础题 中有讲到
匿名内部类
是我们平时使用的最多内部类,比如在我们Android开发的时候经常写的监听器。
静态内部类
其内部只能访问外部的静态成员方法和字段。和静态方法同理,这一点不难理解。
接下来我们先来解决第三个问题:组合和内部类之间的区别。
很多刚接触Java的小伙伴。可能会觉得组合(组合:在当前类声明的外部类)和内部类和类似,两者对于外部类来说都是输入has a关系。二者在使用上确实有一些相似之处,但内部类和组合是两个完全不同的概念,这一点必须要搞清楚。举个简单的例子,组合相当于你手机里安装的有一个360手机卫士,你可以使用手机卫士里面的所有功能,但是你却不知道任何一个功能的实现细节也不能改变其中的任何一个功能。而内部类相当于是你自己高仿的一款手机卫士,功能可能和原版的360手机卫士完全一样,但是你知道每一个功能的实现细节,也能随心所以的修改每一个功能。可以看到组合和内部类可以实现完全一样的功能,但是本质上,二者是有区别的,这一点大家务必要理解。
接下来我们来看第二个问题:内部类为什么能访问外部类的所有成员?
可以看到,我们能在内部类中访问到外部类的所有成员(静态内部类除外),即使是private修饰的。此时的内部类自动拥有了对其外围类所有成员的访问权。其实当某个外围类创建一个一个内部类对象时,此内部类对象必定会秘密地捕获一个指向那个外围类对象的引用。然后每当内部类需要访问外部成员时,其实都是通过这个引用来进行访问的。但貌似我们从来都没有这样处理过,这必须值得庆幸,这一些编译器已经帮我们处理好了所有细节,试想一下如果我们需要自己处理的话。相信大多是developer对内部类只能望文心叹了。
最后我们来看第一个问题:我们为什么要使用Java内部类?
可能大多数小伙伴对于这个问题,都不知从何答起,既然是Sun公司煞费苦心添加的语言特性,并且在各类源码中内部类都随处可见,必然有它非同一般的意义。
首先前两个问题的答案就可以成为我们使用内部类的理由。我们知道Java语言是单继承的,每个Java类只能拥有一个直接父类。而内部类的间接的解决的“多继承的问题”,使得Java语言能够间接的实现多继承。其次,当我们把实现细节放在了内部类中时,相当于是对外隐藏的细节,也就是Java语言三大特性之一的封装性。再者,每个内部类都能独立的继承一个(接口或者抽象类)实现,所以无论外围类是否已经继承了某个(接口或者抽象类),对于内部类都没有影响。内部类可以有多个实例,每个实例都有自己的状态信息,并且与其外围类对象的信息相互独立。
内部类可以很好的实现细节的隐藏,弥补了Java语言单继承的缺陷,可以利用内部类的加载特性,实现一些线程安全问题,比如单例模式中使用静态内部类解决并发的问题
via
Hi小鱼 http://www.imooc.com/article/3129
我们为什么要使用内部类? 内部类为什么能访问外部类的所有成员? 组合和内部类有什么区别?
我们先来看一下什么是内部类:可以将一个类的定义放在另一个类的定义内部,这就是内部类。内部类大概分为下面四种:
成员内部类(也叫非静态内部类)
是最普通的内部类,和成员变量和成员方法属于同一层级,可以访问外部类中的所有方法和字段属性。需要注意的是当内部类中的方法或者字段重名是,使用this和父类命进行区分。
局部内部类
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。当访问局部变量是需要添加final关键字,具体原因在我的另外一篇博客四道Java基础题 中有讲到
匿名内部类
是我们平时使用的最多内部类,比如在我们Android开发的时候经常写的监听器。
静态内部类
其内部只能访问外部的静态成员方法和字段。和静态方法同理,这一点不难理解。
接下来我们先来解决第三个问题:组合和内部类之间的区别。
很多刚接触Java的小伙伴。可能会觉得组合(组合:在当前类声明的外部类)和内部类和类似,两者对于外部类来说都是输入has a关系。二者在使用上确实有一些相似之处,但内部类和组合是两个完全不同的概念,这一点必须要搞清楚。举个简单的例子,组合相当于你手机里安装的有一个360手机卫士,你可以使用手机卫士里面的所有功能,但是你却不知道任何一个功能的实现细节也不能改变其中的任何一个功能。而内部类相当于是你自己高仿的一款手机卫士,功能可能和原版的360手机卫士完全一样,但是你知道每一个功能的实现细节,也能随心所以的修改每一个功能。可以看到组合和内部类可以实现完全一样的功能,但是本质上,二者是有区别的,这一点大家务必要理解。
接下来我们来看第二个问题:内部类为什么能访问外部类的所有成员?
public class Test { private int age = 123; private void show(){ System.out.println(age); } class Inner{ public void innerShow(){ show(); } } }
可以看到,我们能在内部类中访问到外部类的所有成员(静态内部类除外),即使是private修饰的。此时的内部类自动拥有了对其外围类所有成员的访问权。其实当某个外围类创建一个一个内部类对象时,此内部类对象必定会秘密地捕获一个指向那个外围类对象的引用。然后每当内部类需要访问外部成员时,其实都是通过这个引用来进行访问的。但貌似我们从来都没有这样处理过,这必须值得庆幸,这一些编译器已经帮我们处理好了所有细节,试想一下如果我们需要自己处理的话。相信大多是developer对内部类只能望文心叹了。
最后我们来看第一个问题:我们为什么要使用Java内部类?
可能大多数小伙伴对于这个问题,都不知从何答起,既然是Sun公司煞费苦心添加的语言特性,并且在各类源码中内部类都随处可见,必然有它非同一般的意义。
首先前两个问题的答案就可以成为我们使用内部类的理由。我们知道Java语言是单继承的,每个Java类只能拥有一个直接父类。而内部类的间接的解决的“多继承的问题”,使得Java语言能够间接的实现多继承。其次,当我们把实现细节放在了内部类中时,相当于是对外隐藏的细节,也就是Java语言三大特性之一的封装性。再者,每个内部类都能独立的继承一个(接口或者抽象类)实现,所以无论外围类是否已经继承了某个(接口或者抽象类),对于内部类都没有影响。内部类可以有多个实例,每个实例都有自己的状态信息,并且与其外围类对象的信息相互独立。
内部类可以很好的实现细节的隐藏,弥补了Java语言单继承的缺陷,可以利用内部类的加载特性,实现一些线程安全问题,比如单例模式中使用静态内部类解决并发的问题
via
Hi小鱼 http://www.imooc.com/article/3129
相关文章推荐
- 深入理解Java内存模型
- struts1+jdbc增删改查
- java序列化框架
- Java中PDF类如合同打印代码事例
- Java制作证书的工具keytool用法总结
- JAVA软件开发职责
- [转]史上最全Eclipse优化
- Java中write()系列方法
- 彻底解决Spring MVC 中文乱码 问题
- 简单的说下java的泛型?
- Java之美[从菜鸟到高手演变]之设计模式
- Java Swing界面编程(28)---复选框:JCheckBox
- MyEclipse10破解教程(亲测可用)
- Java将流转化为文件
- struts标签错误The Struts dispatcher cannot be found.
- Java上传图片代码事例
- Java中普通代码块,构造代码块,静态代码块区别及代码示例
- springmvc+mybatis
- Spring01-Spring 框架简介
- SpringMVC深度探险(一) ——SpringMVC前传