内部类是什么,简单来说,就是定义在类内部的类(一本正经的说着废话)。

  一个正经的内部类是长这样的:

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内部类——成员内部类的更多相关文章

  1. 【Java入门提高篇】Java集合类详解(一)

    今天来看看Java里的一个大家伙,那就是集合. 集合嘛,就跟它的名字那样,是一群人多势众的家伙,如果你学过高数,没错,就跟里面说的集合是一个概念,就是一堆对象的集合体.集合就是用来存放和管理其他类对象 ...

  2. 【Java入门提高篇】Day9 Java内部类——静态内部类

    今天来说说Java中的最后一种内部类--静态内部类 所谓的静态内部类,自然就是用static修饰的内部类,那用static修饰过后的内部类,跟一般的内部类相比有什么特别的地方呢? 首先,它是静态的,这 ...

  3. 【Java入门提高篇】Day21 Java容器类详解(四)ArrayList源码分析

    今天要介绍的是List接口中最常用的实现类——ArrayList,本篇的源码分析基于JDK8,如果有不一致的地方,可先切换到JDK8后再进行操作. 本篇的内容主要包括这几块: 1.源码结构介绍 2.源 ...

  4. 【Java入门提高篇】Day1 抽象类

    基础部分内容差不多讲解完了,今天开始进入Java提高篇部分,这部分内容会比之前的内容复杂很多,希望大家做好心理准备,看不懂的部分可以多看两遍,仍不理解的部分那一定是我讲的不够生动,记得留言提醒我. 好 ...

  5. 【Java入门提高篇】Day28 Java容器类详解(十)LinkedHashMap详解

    今天来介绍一下容器类中的另一个哈希表———>LinkedHashMap.这是HashMap的关门弟子,直接继承了HashMap的衣钵,所以拥有HashMap的全部特性,并青出于蓝而胜于蓝,有着一 ...

  6. 【Java入门提高篇】Day27 Java容器类详解(九)LinkedList详解

    这次介绍一下List接口的另一个践行者——LinkedList,这是一位集诸多技能于一身的List接口践行者,可谓十八般武艺,样样精通,栈.队列.双端队列.链表.双向链表都可以用它来模拟,话不多说,赶 ...

  7. 【Java入门提高篇】Day13 Java中的反射机制

    前一段时间一直忙,所以没什么时间写博客,拖了这么久,也该更新更新了.最近看到各种知识付费的推出,感觉是好事,也是坏事,好事是对知识沉淀的认可与推动,坏事是感觉很多人忙于把自己的知识变现,相对的在沉淀上 ...

  8. 【Java入门提高篇】Day16 Java异常处理(下)

    今天继续讲解java中的异常处理机制,主要介绍Exception家族的主要成员,自定义异常,以及异常处理的正确姿势. Exception家族 一图胜千言,先来看一张图. Exception这是一个父类 ...

  9. 【Java入门提高篇】Day31 Java容器类详解(十三)TreeSet详解

    上一篇很水的介绍完了TreeMap,这一篇来看看更水的TreeSet. 本文将从以下几个角度进行展开: 1.TreeSet简介和使用栗子 2.TreeSet源码分析 本篇大约需食用10分钟,各位看官请 ...

  10. 【Java入门提高篇】Day26 Java容器类详解(八)HashSet源码分析

    前面花了好几篇的篇幅把HashMap里里外外说了个遍,大家可能对于源码分析篇已经讳莫如深了.别慌别慌,这一篇来说说集合框架里最偷懒的一个家伙——HashSet,为什么说它是最偷懒的呢,先留个悬念,看完 ...

随机推荐

  1. C#与lua相互调用

    Lua是一种很好的扩展性语言,Lua解释器被设计成一个很容易嵌入到宿主程序的库.LuaInterface则用于实现Lua和CLR的混合编程. (一)C#调用Lua 测试环境:在VS2015中建一个C# ...

  2. Python 抽象篇:面向对象之类的方法与属性

    概览:类成员之字段:-普通字段,保存在对象中,执行职能通过对象访问-静态字段,保存在类中,执行可以通过对象访问,也可以通过类访问类成员之方法:-普通方法,保存在类中,由对象来调用,self->对 ...

  3. scp命令,用来在本地和远程相互传递文件,非常方便

    scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的.可能会稍微影响一下速度.当你服务器 ...

  4. Leetcode题解(十七)

    48.Rotate Image 题目: 分析:题目意思很简单,就是将一个n*n的矩阵顺时针旋转90度. 这道题难度不大,按照旋转的过程走一遍即可.代码如下: class Solution { publ ...

  5. 初入红尘——在安联IT实习的一点感受(未完......)

    文章很短,只有800字. 从踏进安联的大门开始,我便入了红尘. 安联的迎客之道 “花径不曾缘客扫,蓬门今始为君开.”我的第一个贵人就是前台的美君姐.由于路况不熟,所以我没把握好时间,到的时候比约定的面 ...

  6. IdentityServer4 通过 AccessToken 获取 UserClaims

    实现效果:通过生成的access_token获取用户的一些信息,这样客户端请求的时候,不需要传递用户信息了. 示例配置: public void ConfigureServices(IServiceC ...

  7. AngularJS学习篇(八)

    AngularJS 服务(Service) 在 AngularJS 中,服务是一个函数或对象,可在你的 AngularJS 应用中使用. AngularJS 内建了30 多个服务. 为什么使用服务? ...

  8. 完善tab页面定位

    当我们用锚点定位到页面某个元素时,接下来按tab的话是想进入到目前元素( id="content")的下一个连接 <a href="#content"&g ...

  9. J1001.Java原生桌面及Web开发浅谈

    自从Java问世以来,在服务端开发方面取得了巨大的发展.但是在桌面/Web开发方面,一直没有得到大的发展.从最初的AWT,到Swing,再到JavaFX,Java从来没有在桌面/Web解决方案中取得重 ...

  10. 运放的PID电路

    PID就是(比例(proportion).积分(integral).导数(derivative)),在工程实际中,应用最为广泛的调节器控制规律为比例.积分.微分控制,简称PID控制,又称PID调节. ...