思维导图
一.什么是内部类,内部类就是在类的内部定义的类
class Outer{
class Inner{}
}
- 创建内部类的引用及实例对象
public class InnerClass {
public static void main(String[] args) {
//创建内部类时,必须先创建一个内部类的实例,因为内部类必然关联一个外部类,拥有一个外部类的引用
Outer outer = new Outer();
//内部类引用的创建 创建实例则需要使用.new语法
Outer.Inner in = outer.new Inner();
}
}
class Outer{
class Inner{}
}
- 特别的,当一个类需要继承内部类
//继承一个内部类时,构造函数中必须加入一个外部类的引用,并在构造函数中调用其构造方法进行初始化
class ExtendsInner extends Outer.Inner{
ExtendsInner(Outer out){
out.super();
}
}
二.内部类的特性
- 可以访问外部类的所有成员,包括私有字段,私有方法等等
class Outer{
private String name = "xiaohao";
private void f() {
}
class Inner{
public void f() {
//内部类可以访问外部类的所有成员,会有隐藏的外部类引用。有特殊需要时,可以使用.this关键字显化外部类引用
Outer.this.f();
System.out.println(name);
}
}
}
- 状态信息与外部类互相独立
- 独立主体,内部类不会像方法一样因为类似重写而被覆盖
//两个Inner类完全独立,不受影响,更不会被覆盖
class Outer{
class Inner{}
}
class ExtendsOuter extends Outer{
class Inner{}
}
三.内部类的分类
1.普通内部类:上方举例就是普通内部类的创建方式及特性
2.嵌套内部类:也叫静态内部类,他比普通内部类多了无需外部类也可以创建的特性及可以拥有静态字段和方法(同时不能访 问外部类的非静态对象)
public class InnerClass {
//可以直接创建嵌套类
Outer2.Inner2 oi2 = new Outer2.Inner2();
}
}
class Outer2{
String name = "xiaohao";
static class Inner2{
static int i = 10;
//不可访问外部类非静态对象
//String name = Outer2.this.name;
}
}
可以将类放入接口中,自然就是嵌套类,可以实现接口的公共功能
interface Teacher{
public void f();
class GoodTeacher implements Teacher{
public void f() {
System.out.println("I am a teacher");
}
}
}
3.匿名内部类:创建必须向上转型,可以传入基类构造器参数
访问外部对象必须使用final关键字
可以使用静态域实现类似于构造器的功能
与工厂模式搭配使用极佳
class Student{
Student(int age){
}
public void f() {}
}
class Game{
public Student getStudent(int age,final String name) {
//如果基类构造器有参数,则传递参数即可
return new Student(age) {
//使用静态域实现类似于构造器的功能
int a;
{
a = 100;
}
//如果想要访问外部参数,则必须使用final传递进来
public void f() {
System.out.println(name);
}
};
}
}
4.局部内部类:在方法体中创建的内部类,类似于匿名内部类的扩展,可以拥有构造器,也可以有多个对象,而不是像匿名内部 类一样,只能返回单一的对象。其访问范围在构建的方法体中
class Teacher{
Teacher(int age){}
public void f() {
class GoodTeacher extends Teacher{
GoodTeacher(int age){
super(age);
}
}
GoodTeacher teacher1 = new GoodTeacher(1);
GoodTeacher teacher2 = new GoodTeacher(2);
}
}
四.内部类的功能
1.内部类补充了Java的多继承体系:Java可以实现多个接口,但是只能继承一个类或者抽象类,使用多个内部类继承多个类或 抽象类可以解决多继承问题
public class InnerClass {
public static void f(GoodStudent gs) {
gs.f();
}
public static void f(BadStudent bs) {
bs.f();
}
public static void main(String[] args) {
Student s = new Student();
f(s.sb);
f(s.sg);
}
}
class GoodStudent{
public void f() {
System.out.println("I am a good student");
}
}
class BadStudent{
public void f() {
System.out.println("I am a bad student");
}
}
class Student{
StudentOfGood sg = new StudentOfGood();
StudentOfBad sb = new StudentOfBad();
class StudentOfGood extends GoodStudent{
public void f() {
System.out.println("I am a good student,la la la");
}
}
class StudentOfBad extends BadStudent{
public void f() {
System.out.println("I am a bad student,la la la");
}
}
}
2.可以隐藏实现的细节:内部类向上转型的返回值可以相当程度的隐藏实现细节
3.闭包和回调:利用内部类含有外部类引用的特性以回滚状态
4.控制框架:多个内部类实现同一接口的模板模式
五. .class文件的命名
1.匿名内部类:外部类+$+数字(1,2,3。。。。)
2.非匿名内部列:外部类+$+内部类