Java内部类
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java内部类相关的知识,希望对你有一定的参考价值。
内部类
通常情况
一个 Java 文件中只有一个主类,也就意味着下面这样是错误的:
// 编译器会报错,一个 java 文件中只能有一个被 public 修饰的类,并且该类的类名与 java 文件名一致(Outer.java)
public class Outer{
}
public class Other{
}
将第二个类的 public 权限修饰符删除,就可以在 java 文件中定义多个类
并且每个类都可以被访问到
内部类的结构
内部类,顾名思义,就是 java 一个类中定义另一个类,如下所示:
public class Outer{
class Inter{
}
}
创建内部类
内部类在实例化的时候偷偷保留了指向外部类的引用。因此在创建内部类对象的同时,必须先创建外部类对象(静态内部类除外)
- 通过外部类中的方法得到内部类
public class Outer{
public Inter inter() {
return new Inter();
}
class Inter{
}
public static void main(String[] args) {
Outer outer = new Outer();
Inter inter = outer.inter();
}
}
- 内部类对象通过 外部类对象的 .new 方法创建
public class Outer{
class Inter{
}
public static void main(String[] args) {
// 通俗易懂的创建方式
Outer outer = new Outer();
Outer.Inter inter0 = outer.new Inter();
// 一次创建完毕
Inter inter1 = new Outer().new Inter();
Outer.Inter inter2 = new Outer().new Inter();
}
}
内部类对象通过 外部类.this 方法得到父类
public class Outer{
class Inter{
Outer getOuter() {
return Outer.this;
}
}
public static void main(String[] args) {
Outer outer1 = new Outer();
Outer.Inter inter = outer1.new Inter();
Outer outer2 = inter.getOuter();
// 两个对象是同一个
System.out.println(outer1 == outer2); // true
}
}
内部类的特点
内部类默认可以访问外部类中所有的成员
public class Outer{
Object[] items = new Object[2];
private int index = 0;
class Inter{
public void add(String s) {
// 在Inter类中,可以访问到外部的private成员变量
if (index<items.length) items[index++]=s;;
}
}
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inter inter = outer.new Inter();
inter.add("元素一");
inter.add("元素二");
System.out.println(outer.items[1]); // print:元素二
}
}
内部类与向上转型
将内部类声明为private或者protected。同时,在创建内部类实例对象的时候,通过内部类的父接口来声明对象变量,这样一来,客户端程序员就只能访问接口中定义的公共方法。因而实现了对接口实现过程代码的隐藏。
public class Outer{
public Inter inter() {
return new Inter();
}
interface People{
void speak();
}
class Inter implements People{
public void speak() {
System.out.println("这是接口中的一个方法");
}
public void sleep(){
}
}
public static void main(String[] args) {
// 程序员无法访问到内部类实现的接口以外的方法
Outer outer = new Outer();
People inter = outer.inter();
inter.speak();
// inter.sleep() 访问不到
}
}
在方法中和作用域内的内部类
内部类可以在方法里面或者在任意的作用域中定义内部类。
匿名内部类
看起来就像创建类对象的时候,同时在这里插入该类的定义。
用的比较多的:
new 接口(){ 接口的实现 }
,这样就不用再定义具体的一个实现类了
public class Outer{
// 接口
interface Inter{
void speak();
}
public Inter inter() {
// 返回的时候,将接口实现
return new Inter(){
public void speak() {
System.out.println("hello");
}
};
}
}
嵌套类(静态内部类)
使用 static 修饰的内部类就是嵌套类了。内部类不依赖于外部类对象,没有 .this
方法,普通内部类中不能有static方法或成员和嵌套类。而嵌套类里边可以有static方法和成员,也可以继续嵌套一个类
public class Outer{
static class Inter{
static String des = "静态成员变量";
static void speak() {
System.out.println("静态方法");
}
static class InterInter{
static {
String des = "嵌套类中的嵌套类";
}
}
}
public static void main(String[] args) {
Inter.speak();
}
}
- 接口内部的嵌套类
接口中的类都会被声明为public,static。可以通过在接口内部写一个嵌套类,并且在这个嵌套类中创建公共代码
每个类中测试的时候都需要主方法,但是你可以在一个嵌套类中定义一个main方法,这样外部类在解析这个嵌套类的时候会执行其中的静态main方法,从而外部类不用特意写个主方法了
- 无论嵌套多少层都没事,嵌套类总能访问外部类的成员(无论其访问修饰符是什么),最里层的嵌套类可以访问外层的所有成员
为什么使用内部类
每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否及经济成了某个(接口的)实现,对于内部类都没有影响
- 可以解决多重继承问题
- (闭包与回调)通过内部类提供闭包的功能是优良的解决方案,他比指针更灵活、更安全。
闭包(closure)是一个可调用的对象,他记录了一些信息,这些信息来自创建它的作用域。
- 内部类和控制框架
每个内部类都可以独立地实现一个action
内部类可以很容易访问外围类的任意成员
以上是关于Java内部类的主要内容,如果未能解决你的问题,请参考以下文章