文章目录

  • 内部类
  • 成员内部类
  • 局部内部类
  • 匿名内部类
  • 概念
  • 格式
  • 原理


内部类

  1. 内部类仍然是一个独立的类,在编译后内部类会编译成独立的.class文件,但是前面会冠以外部类类名+$符号
  2. 内部类不能用普通的方式访问。内部类是外部类的一个成员,,因此内部类可以自由地访问外部类的成员变量,无论是否用private修饰

成员内部类

在类的成员位置,即和成员变量以及成员方法所在的位置是一样的。在内部类中,可以直接访问外部类的成员,包括私有的private成员。
eg:

public class InnerDemo{
	public static void main(String[] args){
		Outer o = new Outer();
		o.method(); //结果为“我是内部类的方法10”
		Outer.Inner i = new Outer().Inner(); //先创建Outer类型对象后,再创建Inner对象。
		i.function(); //结果为“我是内部类的方法10”
	}
}
class Outer{
	private int num = 10;
	public void method(){
	Inner i = new Inner();
	i.function();
	}
	class Inner{
		public void function(){
		System.out.println("我是内部类的方法" + num);
		}
	}
}

成员内部类的修饰符:

  1. 可以用权限修饰符修饰成员内部类,但若用private修饰,则无法在其他类中访问
  2. static修饰,不需要先创建外部类对象,可直接使用类名调用
public class InnerDemo{
	public static void main(String[] args){
		Outer o = new Outer();
		o.method(); //结果为“我是静态内部类的方法10”
		Outer.Inner i = new Outer.Inner(); //注意观察,Outer后无括号,直接点出来
		i.function(); //结果为“我是静态内部类的方法10”
	}
}
class Outer{
	private static int num = 10; //注意区别:静态类下的方法只能访问静态成员变量。
	public void method(){
	Inner i = new Inner();
	i.function();
	}
	static class Inner{
		public void function(){
		System.out.println("我是静态内部类的方法" + num);
		}
	}
}

注意区分上述两段代码的区别。

  1. 非静态内部类,创建内部类对象:Outer.Inner i = new Outer().Inner();
  2. 静态内部类,创建内部类对象:Outer.Inner i = new Outer.Inner();

局部内部类

方法内,和局部变量性质相同,出了方法就消失了。

public InnerDemo{
	public static void main(String[] args){
		Outer o = new Outer();
		o.method(); //我是局部内部类的方法
	}
}
class Outer{
	public void method(){
		class Inner{ //局部内部类的位置在方法内部,和局部变量一样,出了方法就消失了
			public void function(){
			System.out.println("我是局部内部类的方法");
			}
		Inner i = new Inner(); //创建局部内部类对象,必须在局部内部类声明之后,放在之前会报错。
		i.function();
		}
	}
}

注意:创建局部内部类对象,必须在局部内部类声明之后,放在之前会报错。

匿名内部类

概念

可以把匿名内部类看做一个没有名字的局部内部类,定义在方法中必须在定义匿名内部类的时候创建它的对象

格式

new 类名/接口名(){}; 实际为一个继承了这个类或实现了这个接口的子类对象,可以直接点出方法(对象.方法()),
new 类名/接口名{ @override function()}.function;

原理

创建了继承了这个类的子类对象或创建了实现这个接口的子类对象

  1. 如果创建了继承这个类的子类对象,可以重写这个父类的方法。
  2. 如果创建了实现这个接口的子类对象,必须实现该接口的所有方法。
    eg:
public class InnerDemo {
	public static void main(String[] args) {
		Outer o = new Outer();
		o.method();
	}
}

interface Inner{
	public abstract void function();
}

class Outer{
	public void method() {
		new Inner() {

			@Override
			public void function() {
				System.out.println("我是匿名内部类的方法");
			}
		}.function();; //这实际为一个对象(匿名对象),也可以把对象中的方法点出来!!!!!!!!!!
	};
}

内部类的使用场景:作为参数进行传递。