18、内部类
内部类就是在一个类的内部定义的类
成员内部类格式如下:
class Outer
{
class Inner//成员内部类
{
}
}
阐述上述代码会产生两个文件:
Outer.class和Outer$Inner.class
1、在外部创建内部类对象:
内部类除了可以在外部类中产生实例化对象,也可以在外部类的外部来实例化。
那么,根据内部类生成的*.class文件:Outer$Inner.class
$在程序运行时将替换成“.”
所以内部类的访问:通过“外部类.内部类”的形式表示。
public class Demo1
{
public static void main(String[] args)
{
Outer outer = new Outer();
//在外部创建成员内部类的实例(因为成员内部类需要依赖外部类的对象,所以会创建一个:对象名.new,注意这个对象名,可能会是小写):
//通常情况下我们不建议这样来实例化内部类对象
Outer.Inner inner = outer.new Inner();
//调用内部类方法:
inner.print();
}
}
class Outer
{
private String name;
class Inner//成员内部类
{
public void print()
{
System.out.println("inner");
}
}
}
/*
结果:
inner
*/
我们这样实例化内部类对象不好。
内部类推出基于的原则是封装的概念,我们来分析一下,为什么会有内部类的概念。
内部类就是在类里面定义的一个类,它是一个类,只是放在了另一个类里面。这就好比,你是一个老板,日理万机,工作很忙,这时候,就可以请一个秘书,帮忙管理,秘书是帮你干活的,他又是一个个体,管下层人员,这就是一个分摊工作的一个角色,他只为你来工作,别人对接的时候不能使唤你的秘书,只能你使唤。同样道理,成员内部类就是外部类的秘书,
public class Demo1
{
public static void main(String[] args)
{
Outer outer = new Outer();
//在外部创建成员内部类的实例:
/*Outer.Inner inner =outer.new Inner();
//调用内部类方法:
inner.print();*/
outer.innerPrint();
}
}
class Outer
{
private String name;
//添加这个方法(建议在外部类中定义一个方法,对外提供访问内部类的接口):
public void innerPrint()
{
Inner inner = new Inner();
inner.print();
}
private class Inner//成员内部类,建议用这种方式
{
public void print()
{
System.out.println("inner");
}
}
}
/*
结果:
inner
*/
这样,主函数就感受不到我们是让这个“秘书”类里面就有一个内部类了,你好像调用了一个类的普通方法,但这个方法就是一个内部类。
2、方法内部类:
内部类可以作为一个类的成员外,还可以把类放在方法内定义。
class Outer
{
public void doSomething()
{
class Inner
{
public seeOuter()
{
}
}
}
}
我们跟着第一个内部类往下写:
public class Demo1
{
public static void main(String[] args)
{
Outer outer = new Outer();
//在外部创建成员内部类的实例:
/*Outer.Inner inner =outer.new Inner();
//调用内部类方法:
inner.print();*/
outer.innerPrint();
outer.show();
}
}
class Outer
{
private String name;
//添加这个方法:
public void innerPrint()
{
Inner inner = new Inner();
inner.print();
}
private class Inner//成员内部类
{
public void print()
{
System.out.println("成员内部类");
}
}
public void show()//方法内部类
{
class Inner2//这里面是内部类
{
public void print()
{
System.out.println("方法内部类");
}
}
}
}
/*
结果:
成员内部类
*/
可以看到,下面的类的方法中定义了内部类,但是没有执行,为什么呢?因为,我们并没有创建内部类的内存,所以内部类的print方法没有打印出来,我们在在内部类下面申请一下内存,就可以了。
public class Demo1
{
public static void main(String[] args)
{
Outer outer = new Outer();
//在外部创建成员内部类的实例:
/*Outer.Inner inner =outer.new Inner();
//调用内部类方法:
inner.print();*/
outer.innerPrint();
outer.show();
}
}
class Outer
{
private String name;
//添加这个方法:
public void innerPrint()
{
Inner inner = new Inner();
inner.print();
}
private class Inner//成员内部类
{
public void print()
{
System.out.println("成员内部类");
}
}
public void show()//方法内部类
{
class Inner2
{
public void print()
{
System.out.println("方法内部类");
}
}
Inner2 inner2 = new Inner2();//增加这行跟下面这行
inner2.print();
}
}
/*
结果:
成员内部类
方法内部类
*/
注意:
1、方法内部类只能在定义该内部类的方法内实例化,不可以在此方法外实例化(必须在方法内部类里面实例此内部类)。
2、方法内部类对象不能使用该内部类所在方法的非final变量(解释看下面show方法的代码)。
public class Demo1
{
public static void main(String[] args)
{
Outer outer = new Outer();
//在外部创建成员内部类的实例:
/*Outer.Inner inner =outer.new Inner();
//调用内部类方法:
inner.print();*/
outer.innerPrint();
outer.show();
}
}
class Outer
{
private String name;
//添加这个方法:
public void innerPrint()
{
Inner inner = new Inner();
inner.print();
}
private class Inner//成员内部类
{
public void print()
{
System.out.println("成员内部类");
}
}
public void show()//方法内部类,show方法的局部变量或方法的参数,必须是常量,它会自动加入final(在JDK1.8之后可以不加final)
{
int x = 10;
class Inner2
{
public void print()
{
x++;//这里就会出现错误: 从内部类引用的本地变量必须是最终变量或实际上的最终变量,因为上面的x=10这个10就已经是最终变量了,int x = 10;可以理解成final int x = 10;
System.out.println("方法内部类"+x);
}
}
Inner2 inner2 = new Inner2();//增加这行跟下面这行
inner2.print();
}
}
上面代码,要是不改变x的值,输出x是可以的,包括在这个show方法,往里传的参数一定要是final的,不可改变的。假如在shuw的参数里加一个int i,其实就是加了final int i,输出时也是只能访问,不能改变。