内部类

将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类。

内部类的分类

  1. 成员内部类,类定义在了成员位置 (类中方法外称为成员位置)
  2. 局部内部类,类定义在方法内

成员内部类 :定义在类中方法外的类。

class 外部类{
	// 成员变量
	// 成员方法
	class 内部类{
		// 成员变量
		// 成员方法
	}
}

内部类可以直接访问外部类的成员,包括私有成员

创建内部类对象格式:
外部类名.内部类名 对象名 = new 外部类型().new 内部类型();

内部类仍然是一个独立的类,在编译之后会内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号 。

比如,Axx$Bxx.class

局部内部类 :定义在方法中的类

class 外部类名 {
	数据类型 变量名;
	
	修饰符 返回值类型 方法名(参数列表) {
		// …
		class 内部类 {
		// 成员变量
		// 成员方法
		}
	}
}

匿名内部类

匿名内部类 :是内部类的简化写法。它的本质是一个 带具体实现的父类或者父接口的匿名的子类对象

匿名内部类必须继承一个父类或者实现一个父接口。

格式:

new 父类名或者接口名(){
	// 方法重写
	@Override
	public void method() {
		// 执行语句
	}
};

以接口为例,匿名内部类的使用,代码如下:

public class Demo1 {
	public static void main(String[] args) {
		new Swim(){
			@Override
			public void swiming() {
				System.out.println("蛙泳....");
			}
		}.swiming(); //蛙泳....
		
		//返回一个实现了swim接口的子类对象,只不过该对象是匿名的
		Swim swim = new Swim() {
			@Override
			public void swiming() {
				System.out.println("仰泳...");
			}
		};
		swim.swiming(); //仰泳...
	}
}
//定义游泳接口
interface Swim{
	void swiming();
}
//定义实现类,实现该接口
class Person implements Swim{
	@Override
	public void swiming() {
		System.out.println("蛙泳.....");
	}
}

匿名内部类的本质

  1. 定义一个没有名字的内部类
  2. 这个类实现了Swim接口
  3. 创建了这个没有名字的类的对象

匿名内部类的使用场景

通常在方法的形式参数是接口或者抽象类时,也可以将匿名内部类作为参数传递。

public class Demo1 {
	public static void main(String[] args) {
		// 普通方法
		Student s1 = new Student();
		swim(s1);
		// 使用匿名内部类方式,创建了一个匿名的类,该类实现了Swim接口
		swim(new Swim() {
			@Override
			public void swiming() {
				System.out.println("狗刨式游泳....");
			}
		});
		swim(new Swim() {
			@Override
			public void swiming() {
				System.out.println("蛙泳....");
			}
		});

	}

	// 模拟,请一些人去游泳
	public static void swim(Swim s) {
		s.swiming();
	}

}

// 定义游泳接口
interface Swim {
	void swiming();
}

// 定义实现类,实现该接口
class Student implements Swim {
	@Override
	public void swiming() {
		System.out.println("狗刨式游泳.....");
	}
}