什么是内部类?

类中定义类,在一个类的内部定义一个完整的类就叫做内部类
例如:

public class TestInner {
	public static void main(String[] args) {
		Outer o = new Outer();

		Outer.Inner inner = o.new Inner();

		inner.inner_method();
	}
}

class Outer{
	int a = 20;	//Outer类的成员变量
	//类中定义类
	class Inner{  //成员内部类
		int a = 10;
//		static int b;  成员内部类中不能定义静态成员(静态方法 和 静态变量)
		public void inner_method(){
			int a = 30;
			System.out.println(a);  //局部变量   30
			System.out.println(this.a);  //内部类的成员变量  10
			System.out.println(Outer.this.a);  //外部类的成员变量   20
			
		}
	}
	
}

从上面程序中可以看出:
Inner就叫做Outer 的 内部类,也是两个完全独立的类

编译后内部类会会生成对应的.class文件,文件名Outer$Inner.class
可以访问外部类的私有属性,从而不破坏外部类的封装性

成员内部类:
在类里面的类就叫成员内部类
可以类比于成员变量,定义在类以内,方法以外。
还借助于上面的程序,
创建成员内部类对象,必须先创建外部类对象,再通过外部类对象.new 构造内部类对象

	Outer outer = new Outer();
	Outer.Inner inner = outer.new Inner();

外部类类名.this指向外部类的当前对象: System.out.println(Outer.this.a); //外部类的成员变量 20

成员内部类中不能有静态成员

public class TestMemberClass {

	public static void main(String[] args) {
	
		Outer o1 = new Outer(120);
		Outer o2 = new Outer(200);
		Outer.Inner in = o1.new Inner();
		in.print();  
	}

}


class Outer{
	private int a ;
	
	//Inner就叫做Outer 的 内部类,也是两个完全独立的类
	//在类里面的类就叫成员内部类
	/*
	 * 1,内部类可以 访问外部类的私有成员,而不破坏封装
	 */
	
	public Outer() {
	}

	public Outer(int a) {
		this.a = a;
	}

	public class Inner{
		//成员内部类中不能有静态成员
		//private int s = 20;
		int a = 123;
		public void print(){
			
			//外部类类名.this指向外部类的当前对象
			System.out.println(a);//123
			System.out.println("---"+Outer.this.a);//120
		} 
	}	
}

Outer.this 代表外部类对象
Outer.this.外部类属性名           访问外部类属性
Outer.this.外部类方法名(实参) 访问外部类方法

静态内部类:
可以类比于静态变量,成员内部类加上static就是静态内部类。也是定义在类以内,方法以外,被static修饰。

class Outer{

   static class Inner{
		
	}
}

创建的时候需要依赖类来创建对象:

Outer.Inner inner = new Outer.Inner();

静态内部类中只能访问外部类的静态成员

局部内部类:
也是类比于局部变量,要定义在方法以内!

class Outer{
	public void method(){
			//类写在方法的内部,就叫做局部内部类
			class inner{
				
			}
		}
}

局部内部类创建对象的时候只能在定义它的方法内部进行创建;

class Outer{
	private int a = 10;
	public void m1(){
		final int b = 20;
		class Inner{
			public void inner_method(){
				System.out.println(a); 	//10
				System.out.println(b); 
				System.out.println("局部内部类方法");
				
			}
		}
		Inner inner = new Inner();
		inner.inner_method();
	}
}

并且局部内部类可以去访问外部类的私有属性
局部内部类也可以去访问它所在方法的局部变量,但是要求局部变量必须被final修饰
jdk 8.0开始,默认为局部变量添加final

匿名内部类:
特殊的局部内部类。局部内部类有的特征它都有
匿名内部类
使用的三个条件

  • 1)特殊的局部内部类
  • 2)继承一个类或者实现一个接口
  • 3)只会创建该类的一个对象

匿名内部类的写法
new 接口(){实现方法};
匿名内部类无法定义构造方法

定义匿名内部类的写法:定义类、实现接口、new对象 三步合一

IA ia = new IA(){		//IA 接口名  匿名内部类想要实现的接口
				public void m1() {
					System.out.println("匿名内部类");
				}
			};
			//ia引用 可以直接操作内部类中方法
			ia.m1();

下面展示一个匿名内部类的具体用法:

package test;

public class TestNiMingClass {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		 Teacher t = School.getTeacher(0);
		 t.teach();
	
	}

}


class School{
	public static Teacher getTeacher(int i){
		//两个局部内部类
		class Teacher1 implements Teacher{
			public void teach(){
				System.out.println("胡老师讲课");
			}
		}
		class Teacher2 implements Teacher{
			public void teach(){
				System.out.println("刘老师讲课");
			}
		}
		
		if (i%2 == 0) {
			//return new Teacher1();
			
			//定义匿名内部类的写法
			//定义类、实现接口、new对象 三步合一  

			
			//局部内部类用法
			//return new Teacher1(); 
			
			//匿名内部类用法
			return new Teacher(){
				public void teach(){ 
					System.out.println("胡老师讲课");
				}
			}; 
		}else{
			return new Teacher2();
		}

	}
}
interface Teacher{
	void teach();
}

匿名内部类的好处:
接口公开,接口的实现类作为内部类隐藏起来,强制弱耦合
缺点是匿名内部类的写法真难受,可读性太差