Java各种内部类解析
-目录-
内部类
Java Class是一种行为规范,它不只是可以定义在packge中,还可以定义在方法里,分支结构里…
按照定义的位置可以分为:
- 成员内部类 packge
- 局部内部类 方法、分支结构
成员内部类
成员内部类定义在外部大的Class内。成员内部类的特点:
- 既拥有自己独立的变量和方法,又可以获取到外部类的变量和方法,也能获取到外部类的引用
- 可以让多个内部类以不同的方式实现同一个接口,或者继承不同的类,实现多继承
- 创建内部类对象并不依赖于外部类对象的创建
- 其他类都不能访问到内部类,提供了更好的封装
public class TestC {
int outA = 1;
public static void main(String[] args) {
TestC testC = new TestC();
Ex1 ex1 = testC.new Ex1();
Ex2 ex2 = testC.new Ex2();
// 外部类改变内部类的值(继承来的)
ex1.num = 1;
ex2.num = 2;
ex1.sonFunc();
ex2.sonFunc();
ex1.reOuterClass().outA = 2;
}
class Ex1 extends Son1Class {
// 内部类获取到外部类的引用
TestC reOuterClass() {
return TestC.this;
}
// 内部类更改外部类变量
void changeNum() {
outA = 2;
}
}
class Ex2 extends Son2Class {}
}
class Son1Class {
int num;
void sonFunc() {}
}
class Son2Class {
int num;
void sonFunc() {}
}
局部内部类
作用域很小,只在定义区域有效,用于实现某些私有的功能
public class TestC {
public static void main(String[] args) {
// 类似结构体
class InnerClass {
int age;
String name;
InnerClass(int age, String name) {
this.age = age;
this.name = name;
}
void sayString() {
System.out.println("My profile is" +
"age=" + age +
", name='" + name);
}
}
InnerClass peopleA = new InnerClass(18, "Jack");
InnerClass peopleB = new InnerClass(25, "Bob");
InnerClass[] people = {peopleA, peopleB};
for (InnerClass p : people) {
p.sayString();
}
}
}
匿名内部类
无名,创建即使用。匿名内部类创建时和原类有中类似继承的微妙关系。匿名类可以覆写原类的方法,可以添加变量和原类没有的方法,但都只在创建时的作用域有效,创建完成后就访问不到了。
public class TestC {
void getClass(TestD testClass) {
// 访问的是原类中的num
System.out.println(testClass.num);
testClass.sayString();
testClass.sayString2();
// testClass.sayString3();错误,不能访问到
}
public static void main(String[] args) {
int a = 0;
new TestC().getClass(new TestD() {
// 可以定义任何变量,但是这个变量只在当前创建类时的作用域有效
int num = 2;
// a=1;错误,不可更改局部变量,但可以访问。这体现了与JAVA闭包的不同
a;
// 如果要定义同名方法就要覆写,类似于子类的关系,不能创建新的方法
@Override
public void sayString2() {
System.out.println("The num is " + num);
System.out.println("Anonymous function OK");
}
// 可以定义原类中没有的方法,但是当匿名类作为参数传入时,是没有意义的,访问不到
// 因为需要这个类的方法是基于原来的类TestD考虑的,没有考虑到你新增方法,
public void sayString3() {
}
});
}
}
class TestD {
int num = 1;
void sayString() {
System.out.println("The num is " + num);
System.out.println("Class function OK");
}
void sayString2() {
}
}
//输出
//1
//The num is 1
//Class function OK
//The num is 2
//Anonymous function OK
静态内部类
使用了static修饰的内部类即为静态内部类,和普通的成员内部类最大的不同是:
- 静态内部类不能引用外部类,即在内部类里使用
OuterClass outerClass = OuterClass.this是错的。 - 它的创建不需要依赖于外围类,但也不能够使用任何外围类的非static成员变量和方法
public class TestC {
int num;
// 静态内部类
static class InnerClass {
int age;
String name;
// TestC testC = TestC.this;错误
// num=1;错误
}
}
class TestD {
// 无需要先行new TestC
TestC.InnerClass innerClass = new TestC.InnerClass();
}