【注意,本人小白一个,以下是个人根据教程的理解,如有疑惑,出错的地方,希望大家能够留言指出来,相互学习进步。】
一个类里面包含有另一个类,则这个被包含的类叫做内部类,包含的类是称为宿主类,内部类只能被它的宿主类使用,所以内部类的使用可以很好地控制类的可见性。 内部类的形式是在一个类中存在有一个类(内部类),而这个内部类可以访问它的宿主类中的变量。
演示例子:
//外部类
class Outer {
String out_string = "String in Outer";
void useIner() {
Iner in = new Iner();
in.print();
}
// 内部类
class Iner {
void print() {
System.out.println("Iner.print()");
System.out.println("use\'" + out_string + "\'");
}
}
}
public class InnerClassDemo {
public static void main(String[] args) {
// 创建一个对象
Outer out = new Outer();
// 调用该类的内部类定义的方法
out.useIner();
}
}
运行结果:
Iner.print()
use'String in Outer'
从main方法里面看,main方法中实例化了Outer类对象,然后调用Outer类里面的useIner方法,而这个useIner方法中实例化了内部类Iner类对象,并且调用Iner类中的print方法。从这些流程可以看出来内部类的时候用流程,要想使用类中的内部类,要通过外部的类去访问里面的类。
静态内部类和非静态内部类
教程中说到,内部类也分两大类,静态的和非静态的,非静态内部类就是上一个例子所展示的内容而静态内部类,根据名称“静态”就知道,需要使用关键字“static”来修饰,一些特性和“static”是相同的,静态内部类不能像非静态内部类那样直接的访问到宿主类的成员,而是必须通过对象来访问。演示例子:
class Outer {
String out_string = "String in Outer";
void useIner1() {
Iner1 in1 = new Iner1();
in1.print();
}
void useIner2() {
Iner2 in2 = new Iner2();
in2.print();
}
// 非静态内部类
class Iner1 {
void print() {
System.out.println("Iner1.print()");
// 可以直接使用宿主类的变量
System.out.println("Outer.out_string=" + out_string + "");
}
}
// 静态内部类
static class Iner2 {
void print() {
System.out.println("Iner2.print()");
// System.out.println("Outer.out_string=" + out_string + "");
// 需要使用对象来方法宿主类的变量
Outer outer = new Outer();
System.out.println("Outer.out_string=" + outer.out_string);
}
}
}
public class InnerClassDemo2 {
public static void main(String[] args) {
Outer out = new Outer();
out.useIner1();
out.useIner2();
}
}
运行结果:
Iner1.print()
Outer.out_string=String in Outer
Iner2.print()
Outer.out_string=String in Outer
首先关注的是静态内部类,在对比非静态内部类,由静态内部类中的print方法可以看到,如果静态内部类需要访问宿主类的成员就要对宿主类实例对象出来,通过对象去访问宿主类的成员,而非静态内部类就不需要实例化宿主类的对象,直接就可以访问到宿主类的成员。
宿主类访问内部类成员变量,这两种不同的内部类有不同的方法,静态内部类的静态变量可以直接用“类名.变量名”来调用。对于静态内部类的非静态变量则就要生成它的对象。利用对象来访问,而非静态内部类里面是不包含静态变量的,这样访问非静态内部类的变量就要创建非静态内部类的对象来访问。
演示例子:
class Outer {
String out_string = "String in Outer";//外部类成员变量
void print() {
// System.out.println(Iner1.this.in_string1);
// 创建内部类对象
Iner1 in1 = new Iner1();//实例化Iner1内部类对象
// 通过对象访问非静态内部类的属性
System.out.println(in1.in_string1);通过对象访问非静态内部类的成员变量
// 直接访问静态内部类的属性
System.out.println(Iner2.in_string2);直接用“类.变量名”访问静态内部类的成员变量
}
class Iner1 {//内部类
String in_string1 = "String in Iner1";
Iner1() {
System.out.println("Constructor of Iner1");
}
class InClass_In_Iner1 {//内部类里面的内部类
}
}
static class Iner2 {
static class staticClass_In_Iner2 {
}
static String in_string2 = "static String in Iner2";
Iner2() {
System.out.println("Constructor of Iner2");
}
}
}
public class InnerClassDemo3 {
public static void main(String[] args) {
// 创建 Outer 类的对象
Outer outer = new Outer();
outer.print();
// 使用类的内部类
Outer.Iner1 in1 = new Outer().new Iner1();
Outer.Iner2 in2 = new Outer.Iner2();
Outer.Iner1.InClass_In_Iner1 inin2 = new Outer().new Iner1().new InClass_In_Iner1();
Outer.Iner1.InClass_In_Iner1 inin1 = in1.new InClass_In_Iner1();
System.out.println(in1);
System.out.println(in2);
System.out.println(inin1);
System.out.println(inin2);
}
}
运行结果:
Constructor of Iner1
String in Iner1
static String in Iner2
Constructor of Iner1
Constructor of Iner2
Constructor of Iner1
Outer$Iner1@14318bb
Outer$Iner2@ca0b6
Outer$Iner1$InClass_In_Iner1@10b30a7
Outer$Iner1$InClass_In_Iner1@1a758cb
局部内部类
这里插入一个信息点:变量创建在类中,叫做成员变量,如果定义在方法中,叫做局部标量。
内部类也是一样,如果在方法中创建,那就叫做局部内部类。
演示例子:
public class Class_In_Method {
void doit() {
// 方法中定义的类
class Class_in_method {
Class_in_method() {
System.out.println("Constructor of Class_in_method");
}
}
new Class_in_method();//调用方法中的内部类
}
public static void main(String[] args) {
Class_In_Method cim = new Class_In_Method();
cim.doit();
}
}
运行结果:
Constructor of Class_in_method
由例子可以看出来,实例化外部类对象cim,调用对象的方法doit,方法中有局部内部类,局部内部类后面有个new局部内部类的实例,这时候才会执行局部内部类的方法。
匿名内部类
匿名内部类就是没有名字的内部类,匿名内部类省去了类的名字,直接构造对象,利用它可以很方便地在需要的时候构造一些只是当前需要的对象。比较下面两个程序:
【1】
//类 Constant
class Constant {
int n;
Constant(int i) {
n = i;
}
}
// 类 ConstantDemo
class ConstantDemo {
// 该方法获得一个 Constant 对象
Constant getConstant() {
return new Constant(5);
}
}
public class NoNameInerClass {
public static void main(String[] args) {
ConstantDemo cd = new ConstantDemo();
System.out.println(cd.getConstant().n);
;
}
}
【2】
//匿名内部类的使用
public class NoNameInerClass2 {
Constant getConstant() {
return new Constant(5) {
int n = 5;
};
}
public static void main(String[] args) {
NoNameInerClass2 nnic = new NoNameInerClass2();
System.out.println(nnic.getConstant().n);
;
}
}
教程没有过多的介绍匿名内部类,这里说一下,了解个大概样子,有个印象。今后学习到再深入了解,