内部类,将一个类A定义在另外一个类B的内部,那么我们就称类A为内部类
1.成员内部类
实验探究:
创建类Test
public class Test {
public static void main(String[] args) {
}
}
创建一个类Out代表外部类,一个类In代表内部类,在类中声明各种属性
class Out {//java中并不推荐在命名中使用_来定义变量名和方法名,但为了表述直观,这里暂
且这么做。
int out_a;//定义一个外部类成员变量
static int static_out_a;//定义一个外部类静态成员变量
void out_print(){//定义一个外部类成员方法
}
static void static_out_print(){//定义一个外部类静态成员方法
}
class In {
int in_a;//定义一个内部类成员变量
//static int static_in_a; //定义一个内部类静态成员变量,见注解①
static final int final_in_a=10;//静态final常量是允许被定义的
void in_print(){
}
//static void static_out_print(){//定义一个内部类静态成员方法,见注解
①
//}
}
}
注解①:这时候,我们发现成员内部类中是不允许定义静态变量和静态方法的,但是可以定义静
态常量
然后我们试图在main方法里创建内部类对象,于是输入In in=new In(),这时候程序报错了,因
为成员内部类对象的创建依赖于外部类对象,于是修改代码为
Out out = new Out();
Out.In in = out.new In();
或者Out.In in=new Out().new In();编译成功。
尝试在内部类的方法中访问外部类的成员,不管是out_a还是static_out_a,或者方法,添加了
private修饰符的变量,都可以访问得到并且不报错,内部类可以访问外部类的一切成员,即包括
了任何属性和方法。
接下来,我们在外部类和内部类中同时声明相同的String变量same和相同的方法print(),两个
print()方法中打印变量的值:System.out.println("In same String:"+same);在main方法中再
创建一个Out对象,注意了,不能直接再new一个对象出来,因为那样的话跟原来的代码指向的不
是同一个对象:
Out.In in=new Out().new In();
Out out=new Out();---->错误。
修改为
Out out=new Out();
Out.In in=out.new In();----->正确
两个对象各自调用方法
in.print();
out.print();
输出结果为:
In same String:same
out same String:same
然后在内部类中的print()方法添加语句Out.this.same="out_same";Out.this.print();再次打印
,得到:
In same String:same
out same String:out_same
out same String:out_same
这说明在外部类和内部类中拥有同名的变量和方法时,可用外部类名.this.成员名的形式来指明
其为外部类的对象的成员。不过这种形式只能在方法体内进行,并且是非静态的或者静态的常量
(这很好理解,因为内部类可以定义静态的常量,但不能定义非静态变量和方法)
成员内部类的定义可以加入访问控制符:
添加private 只能在本类中访问
添加protected 不同包情况下,只能访问外部类的子类
添加public 都可以访问
public classTest {public static voidmain(String[] args) {//In in = new In();//创建内部类对象失败,成员内部类对象的创建依赖于外部类对象//Out out = new Out();//Out.In in = out.new In();//创建内部类对象成功//Out.In in = new Out().new In();//创建内部类对象成功
Out out = newOut();
Out.In in=out.newIn();
in.print();
out.print();
}
}class Out {//java中并不推荐在命名中使用_来定义变量名和方法名,但为了表述直观,这里暂且这么做。
int out_a;//定义一个外部类成员变量
static int static_out_a;//定义一个外部类静态成员变量
private intprivate_out_a;
String same= "same";//定义外部类和内部类的同名属性
static final int final_out_a = 9;void out_print() {//定义一个外部类成员方法
}void print() {//定义外部类和内部类的同名方法
System.out.println("out same String:" +same);
}static void static_out_print() {//定义一个外部类静态成员方法
}classIn {int in_a;//定义一个内部类成员变量//static int static_in_a;//定义一个内部类静态成员变量
static final int final_in_a = 10;//静态final常量是允许被定义的
String same = "same";voidin_print() {
private_out_a= 10;
System.out.println("private_out_a:" +private_out_a);
}voidprint() {
Out.this.same="out_same";
System.out.println("In same String:" +same);
Out.this.print();
}//Out.this.print();//错误,只能在方法内调用
}
}
2.静态内部类
我们先看下这段代码
packagecom.epilogue.day1;classOut {int out_a = 5;static int out_static_a = 5;static classIn {static int in_static_a;//注解①
static void in_static_print() {//注解①//System.out.println("out_a = "+out_a);//错误,注解②
System.out.println("out_static_a = " +out_static_a);
System.out.println("静态内部类的静态方法");
}intb;voidin_print() {//System.out.println("out_a = "+out_a);//错误,注解②
System.out.println("out_static_a = " +out_static_a);
System.out.println("静态内部类的非静态方法");
}
}
}public classTest {public static voidmain(String[] args) {
System.out.println(" Out.In.a = " + Out.In.in_static_a);//访问静态内部类的静态成员,注解③
Out.In.in_static_print();//访问静态内部类的静态成员,注解③
Out.In in = new Out.In();//创建内部类对象,注解④
System.out.println("b = " + in.b);//访问静态内部类的非静态成员:
in.in_print();
}
}
注解①:可以看出,静态内部类是可以定义静态成员的
注解②:静态内部类的内部不能访问外部类的非静态成员:静态内部类对象不依赖外部类的对象
注解③:当外部内要访问内部类的静态成员时,只需要外部类名.内部类名.静态成员名即可调用
注解④:创建内部类对象只需用外部类名.内部类名 对象名=new 外部类名.内部类名()即可
局部内部类
/** 局部内部类:类比局部变量。
* 1.只能在定义的代码块中使用
* 2.局部内部类不能加访问控制符和static
* 3.局部内部类中的成员不能加static,但是可以加访问控制符
* 4.局部内部类可以访问外部类的任何成员
* 5.局部内部类中的方法要访问局部变量的话,局部变量必须是final的
* 6.局部内部类必须先定义后使用
*
**/
classOuter{int a = 8;voidOuterfunc(){
System.out.println("这是外部类的方法");
}voidfunc(){final int x = 5;//局部变量
class Inner{//局部内部类
int a = 88;voidshow(){
Outerfunc();
System.out.println("Outer.this.a = "+Outer.this.a);
System.out.println("局部变量 x = "+x);
System.out.println("局部内部类的方法:");
}
}
Inner inner= new Inner();//创建局部内部类的对象:使用局部内部类必须在类定义之后
inner.show();
}
}public classInnerDemo3 {public static voidmain(String[] args) {//TODO Auto-generated method stub
Outer outer = newOuter();
outer.func();
}
}