【Java入门提高篇】Day6 Java内部类——成员内部类
内部类是什么,简单来说,就是定义在类内部的类(一本正经的说着废话)。
一个正经的内部类是长这样的:
public class Outer {
class Inner{
}
}
这是为了演示而写的类,没有什么luan用,可以看到Inner类置于Outer类的内部。
那为什么要大费周章的在类内部定义一个类呢?不能在类外部定义类吗?内部类跟外部类有什么关系?
确实,很多时候,在外部单独定义一个类确实更加方便,也更加通用,但内部类的存在自然有其存在的道理,内部类作为寄生在外部类的类,可以自由访问外部类的所有的属性和方法,有没有联想其我们之前说的继承,子类可以继承父类的属性和方法,但是内部类有着更高的访问权限,不仅是public属性,protected属性,就连private属性也可以轻松访问,这样就不会让修饰符限制你的想象了(手动滑稽)。
内部类也分很多种:成员内部类、静态内部类、局部内部类、匿名内部类。今天先来说说第一种:成员内部类。
成员内部类是最简单粗暴的内部类,上面那个栗子中的Inner类就是成员内部类,相比普通的类,成员内部类是不能有static修饰的成员或者方法的,因为成员内部类是寄生在外部类中的,所以必须先有外部类实例才能有成员内部类。在外部创建内部类对象时,姿势也不太一样,看起来像是这个样子的:
public class Test {
public static void main(String[] args) {
Outer.Inner inner = new Outer().new Inner();
}
}
在内部类中可以访问外部类的方法和属性,外部类也可以访问内部类的方法和属性,举个栗子:
public class Outer {
private int num;
private Inner inner; Outer(){
num = 1;
inner = new Inner();
} public void print(){
System.out.println("Outer.print()");
System.out.println(inner.num);
System.out.println(num);
} class Inner{
private int num; Inner(){
num = 2;
} public void print(){
System.out.println("Inner.print()");
System.out.println(this.num);
System.out.println(Outer.this.num);
}
}
}
public class Test {
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
outer.print();
inner.print();
}
}
输出如下:
Outer.print()
2
1
Inner.print()
2
1
外部类访问内部类的姿势是先生成内部类实例,然后就能访问所有方法和属性,内部类访问外部类方法和属性则直接使用Outer.属性/方法名 即可。
在这个栗子中,我们可以看到内部了Inner可以对外围类Outer的属性进行无限制的访问,尽管它是private修饰的。因为当我们在创建某个外围类的内部类对象时,会往内部类传入一个外部类的引用,只要我们在访问外部类的成员时,就会用这个引用来选择外围类的成员。引用内部类的时候,需要使用Outer.Inner这样的形式来声明,而不能直接使用Inner来声明(除了在Outer类中),当需要使用到内部类的时候,还是推荐使用getInnerInstance的方式来获取,特别是当内部类只有无参构造器的时候:
public class Outer {
private int num;
private Inner inner; Outer(){
num = 1;
inner = new Inner();
} public Inner getInnerInstance() {
return new Inner();
} public void print(){
System.out.println("Outer.print()");
System.out.println(inner.num);
System.out.println(num);
} public class Inner{
private int num; Inner(){
num = 2;
} public void print(){
System.out.println("Inner.print()");
System.out.println(this.num);
System.out.println(Outer.this.num);
}
}
}
public class Test {
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner inner = outer.getInnerInstance();
outer.print();
inner.print();
}
}
这样的话,就能更好的封装了。
当然,内部类跟外部类还有一个很重要区别:内部类可以用private修饰,而外部类是不能使用private修饰的。如果内部类仅仅在类内部使用时,使用private修饰后,就可以更好的隐藏内部信息。
至此,内部类的第一部分讲解完毕,欢迎大家继续关注。
【Java入门提高篇】Day6 Java内部类——成员内部类的更多相关文章
- 【Java入门提高篇】Java集合类详解(一)
今天来看看Java里的一个大家伙,那就是集合. 集合嘛,就跟它的名字那样,是一群人多势众的家伙,如果你学过高数,没错,就跟里面说的集合是一个概念,就是一堆对象的集合体.集合就是用来存放和管理其他类对象 ...
- 【Java入门提高篇】Day9 Java内部类——静态内部类
今天来说说Java中的最后一种内部类--静态内部类 所谓的静态内部类,自然就是用static修饰的内部类,那用static修饰过后的内部类,跟一般的内部类相比有什么特别的地方呢? 首先,它是静态的,这 ...
- 【Java入门提高篇】Day21 Java容器类详解(四)ArrayList源码分析
今天要介绍的是List接口中最常用的实现类——ArrayList,本篇的源码分析基于JDK8,如果有不一致的地方,可先切换到JDK8后再进行操作. 本篇的内容主要包括这几块: 1.源码结构介绍 2.源 ...
- 【Java入门提高篇】Day1 抽象类
基础部分内容差不多讲解完了,今天开始进入Java提高篇部分,这部分内容会比之前的内容复杂很多,希望大家做好心理准备,看不懂的部分可以多看两遍,仍不理解的部分那一定是我讲的不够生动,记得留言提醒我. 好 ...
- 【Java入门提高篇】Day28 Java容器类详解(十)LinkedHashMap详解
今天来介绍一下容器类中的另一个哈希表———>LinkedHashMap.这是HashMap的关门弟子,直接继承了HashMap的衣钵,所以拥有HashMap的全部特性,并青出于蓝而胜于蓝,有着一 ...
- 【Java入门提高篇】Day27 Java容器类详解(九)LinkedList详解
这次介绍一下List接口的另一个践行者——LinkedList,这是一位集诸多技能于一身的List接口践行者,可谓十八般武艺,样样精通,栈.队列.双端队列.链表.双向链表都可以用它来模拟,话不多说,赶 ...
- 【Java入门提高篇】Day13 Java中的反射机制
前一段时间一直忙,所以没什么时间写博客,拖了这么久,也该更新更新了.最近看到各种知识付费的推出,感觉是好事,也是坏事,好事是对知识沉淀的认可与推动,坏事是感觉很多人忙于把自己的知识变现,相对的在沉淀上 ...
- 【Java入门提高篇】Day16 Java异常处理(下)
今天继续讲解java中的异常处理机制,主要介绍Exception家族的主要成员,自定义异常,以及异常处理的正确姿势. Exception家族 一图胜千言,先来看一张图. Exception这是一个父类 ...
- 【Java入门提高篇】Day31 Java容器类详解(十三)TreeSet详解
上一篇很水的介绍完了TreeMap,这一篇来看看更水的TreeSet. 本文将从以下几个角度进行展开: 1.TreeSet简介和使用栗子 2.TreeSet源码分析 本篇大约需食用10分钟,各位看官请 ...
- 【Java入门提高篇】Day26 Java容器类详解(八)HashSet源码分析
前面花了好几篇的篇幅把HashMap里里外外说了个遍,大家可能对于源码分析篇已经讳莫如深了.别慌别慌,这一篇来说说集合框架里最偷懒的一个家伙——HashSet,为什么说它是最偷懒的呢,先留个悬念,看完 ...
随机推荐
- 将本地web服务映射到公网访问
本文始发于我的个人博客,如需转载请注明出处. 为了更好的阅读体验,可以直接进去我的个人博客看. 项目部署 之前在学习前端的时候项目都只是在本地测试,永远的都是类似 http://localhost/x ...
- 用python爬取微博数据并生成词云
很早之前写过一篇怎么利用微博数据制作词云图片出来,之前的写得不完整,而且只能使用自己的数据,现在重新整理了一下,任何的微博数据都可以制作出来,放在今天应该比较应景. 一年一度的虐汪节,是继续蹲在角落默 ...
- Ionic3 遇到的一些错误-Error: Cannot find module 'reflect-metadata'
E:\Projects\ionic\myApp5>ionic serve Error: Cannot find module 'reflect-metadata' 解决方法: npm insta ...
- windows 系统下C++实现的多线程
摘抄http://blog.csdn.net/huyiyang2010/article/details/5809919 Thread.h #ifndef __THREAD_H__ #define __ ...
- 磁盘管理 之 parted命令添加swap,文件系统
第1章 磁盘管理 1.1 必须要了解的. 1.1.1 ps aux 命令中 RSS 与VSZ的含义 rss 进程占用的物理内存的大小 单位:kb : vsz 进程占用的虚拟的内存大小(物理内存+swa ...
- SQL Server本地连接不上
1.打开SQL Server 2014配置管理器 2.启动服务
- undefined 与void 0
参考:https://segmentfault.com/a/1190000000474941 Javascript中void是一个操作符,该操作符指定要计算一个表达式但是不返回值.void 操作符用法 ...
- Selenium WebDriver 中鼠标和键盘事件分析及扩展[转载]
原文:http://www.ibm.com/developerworks/cn/java/j-lo-keyboard/ 概念 在使用 Selenium WebDriver 做自动化测试的时候,会经常模 ...
- Browsing contexts 浏览器上下文
浏览上下文就是document object 呈现给用户的所在的环境 每一个标签或者窗口都包含一个浏览器上下文,包括iframe frames 每一个browsing context ...
- 使用SQLPLUS创建用户名和表空间
用sqlplus为oracle创建用户和表空间用sqlplus为oracle创建用户和表空间用Oracle10g自带的企业管理器或PL/SQL图形化的方法创建表空间和用户以及分配权限是相对比较简单的, ...