1. 概述
  2. 内部类修饰符
  3. 内部类的细节
  4. 局部内部类
  5. 匿名内部类及其应用
  6. 匿名内部类细节

内部类概述

将一个类定义在另一个类的里面, 里面的那个类就称为内部类(内置类, 嵌套类).

class Outer
{
class Inner // 内部类
{ }
} class InnerClassDemo
{
public static void main(String[] args)
{ }
}
// 上述代码编译完成后, 生成 3 个字节码文件,
// 分别是: InnerClassDemo.class, Outer$Inner.class, Outer.class

访问特点:

  1. 内部类可以直接访问外部类中的成员, 包括私有成员.

    原因是: 内部类持有了外部类的引用, 外部类名.this (具体请见_内部类的细节_)
  2. 外部类要访问内部类中的成员必须要建立内部类的对象

应用场景

  • 一般用于类的设计
  • 分析事物时, 发现该事物 A 描述中还有事物 B, 而且这个事物 B 还在访问被描述事物 A 的内容,

    这时,就把事物 B 定义为内部类来描述.

内部类修饰符

class Outer
{
private int num = 3; class Inner //内部类
{
void show()
{
System.out.println("show run..." + num);
} /*
static void function() // 如果内部类中定义类静态成员, 该内部类也必须是静态的
{
System.out.println("function run..."+ num);
}
*/
}
} class InnerClassDemo
{
public static void main(String[] args)
{
// 直接访问外部类中的内部类成员 (较少见)
Outer.Inner in = new Outer().new Inner();
in.show(); // 如果内部类是静态的, 随着外部类的加载而加载, 不需要建立外部类对象
Outer.Inner in = new Outer.Inner(); // 创建的是内部类对象
in.show(); // 如果内部类是静态的, 内部类的成员也是静态, 此时, 内部类也不需要创建对象
Outer.Inner.function();
}
} // 示例:
class Demo
{
public void func()
{
// 位置一
} class Inner{} public static void main(String[] args)
{
Demo d = new Demo();
// 位置二
}
}
A. 在位置1 写 new Inner(); // 可以
B. 在位置2 写 new Inner(); // 不可以, 因为主函数是静态的, 只能调用静态成员, 所以内部类也必须是 static 的
C. 在位置2 写 new d.Inner(); // new new Demo().Inner(); 格式错误, 正确格式: new Demo().new Inner();
D. 在位置2 写 new Demo.Inner(); // 格式正确, 但是 Inner 必须是静态的.

内部类细节

class Outer
{
int num = 3; class Inner
{
int num = 4; void show()
{
int num = 5;
System.out.println(num); // 输出结果为 5
// System.out.println(this.num); // 输出结果为: 4, 即内部类的 num
// System.out.println(Outer.this.num); // 输出结果为 3, 即外部类的 num
}
} void method()
{
new Inner().show();
}
} class InnerClassDemo
{
public static void main(String[] args)
{
new Outer().method();
}
}

局部内部类

class Outer
{
int num = 3;
void method()
{
final int x = 10;
class Inner
{
void show()
{
System.out.println("show..." + num); // 可以直接访问外部类局部变量 // 内部类在局部位置上只能访问局部中被 final 修饰的局部变量
System.out.println("run..." + x); }
} Inner in = new Inner();
in.show();
}
} class InnerClassDemo
{
public static void main(String[] args)
{
new Outer().method();
}
}

匿名内部类

前提: 内部类必须继承或着实现一个外部类或着接口

匿名内部类, 其实就是一个匿名子类对象, 是内部类的简写格式.

格式: new 父类 or 接口(){子类内容}

abstract class Demo
{
abstract void show();
} class Outer
{
int num = 4;
/* 内部类有名字的情况
class Inner extends Demo
{
void show()
{
System.out.println("show..." + num);
}
} public void method()
{
new Inner().show(); // 调用 show() 方法
}
*/ public void method()
{
new Demo() // 匿名内部类调用 show() 方法
{
void show()
{
System.out.println("show......" + num);
}
}.show();
}
}

匿名内部类应用

当函数参数是接口类型时, 而且接口中的方法不超过三个,

可以用匿名内部类作为实际参数进行传递.

匿名内部类只能访问被 final 修饰的局部变量

匿名内部类细节

class Outer
{
void method()
{
new Object() // 匿名内部类
{
public void show()
{
System.out.println("show run");
}
}.show(); // 此时调用完全没有问题
} void function()
{
Object obj = new Object()
{
public void show()
{
System.out.println("show run");
}
}; obj.show(); // 编译失败, 因为匿名内部类这个子类对象被向上转型为了 Object 类型
// 这样就不能在使用子类特有方法了.
}
}

_参考资料_
- [JavaSE 基础视频](https://www.bilibili.com/video/av3096713/#page=2)
- [final 修饰的原因](https://www.zhihu.com/question/21395848)
- [Java中匿名类的两种实现方式](http://blog.csdn.net/cntanghai/article/details/6094481)

最新文章

  1. MySQL ROOT密码更改
  2. MyEclipse 10.7.1 最新版官网下载地址
  3. PCTF-2016-WEB
  4. saltstack之(十一)扩展组件salt-returners
  5. Apache的https协议配置
  6. oracle“记录被另一个用户锁住”
  7. Lua查找字符串注意
  8. MVC小系列(十六)【在控制器级别或具体Action级别上动态设定模板页(Layout)】
  9. Html.RenderPartial与Html.RenderAction区别(转)
  10. ZOJ 3829 Known Notation (2014牡丹江H称号)
  11. VMware vSphere 服务器虚拟化之十六 桌面虚拟化之VMware Horizon View
  12. Asp.net MVC4 CodeFirst 使用EFTracingProvider
  13. smarty的学习计划(2)
  14. LDAP服务部署
  15. ctrl+shift+r / ctrl+f5 强制(不使用缓存)刷新google chrome网页
  16. 二、Windows Server 2016 AD 组织单位、组、用户的创建
  17. 针对小程序for循环绑定数据,实现toggle切换效果(交流QQ群:604788754)
  18. LuoGu P2420 让我们异或吧
  19. 大数据小白系列——HDFS(2)
  20. NYOJ 布线问题

热门文章

  1. SELinux 宽容模式(permissive) 强制模式(enforcing) 关闭(disabled)
  2. atitit.印度教与java宗教的特点与观念对比 attilax总结
  3. [docker]搭建私有registry
  4. 【Objective-C】02-Objective-C学习及iOS开发的准备
  5. JavaScript学习日志(1)
  6. C#关键字之Partial详解
  7. PHP——做服务
  8. OkHttp+Stetho+Chrome调试android网络部分(原创)
  9. yum 安装出错--"Couldn't resolve host 'mirrors.aliyun.com'"
  10. c#检查网络文件是否存在