java内部类有一下四种

  1. 成员内部类
  2. 静态内部类
  3. 方法内部类
  4. 匿名内部类

一,成员内部类

//外部类
public class Outter {

private int a = 99;
private int e = 700;

// 外部类是不能直接使用内部类的成员和方法
public void outMethod() {

System.out.println("外部类的公共方法,访问外部类成员变量"+a);
//如果外部类想使用内部类的成员变量和方法,必须先实例化内部类
Inner inner = new Inner();
System.out.println("外部类的公共方法,访问外部类成员变量"+inner.c);
}


//内部类
public class Inner{

public int c=77;

private int e = 700;

// 内部类方法可以直接访问 外部类中的数据,而不受访问控制符的影响
public void intMethod() {
System.out.println("成员内部类的公共方法访问外部类成员变量:"+a);
System.out.println("成员内部类的公共方法访问内部类成员变量:"+c);
// 如果外部类和内部类具有相同的成员变量或方法,内部类默认访问自己的成员变量或方法,如果要访问外部类的成员变量,可以使用 this 关键字
System.out.println("成员内部类的公共方法访问外部类成员变量:"+Outter.this.e);
}
}

// 测试
public static void main(String[] args) {

//定义了成员内部类后,必须使用外部类对象来创建内部类对象,而不能直接去 new 一个内部类对象,即:内部类 对象名 = 外部类对象.new 内部类( );
Outter outter = new Outter();
Inner inner = outter.new Inner();
inner.intMethod();
outter.outMethod();

}

}

总结:

  1. 成员内部类相当于外部类的一个成员变量,可以使用任意的访问修饰符
  2. 成员内部类的方法可以访问外部类的任意成员变量而不受访问控制符的影响
  3. 定义了成员内部类后,必须使用外部类对象来创建内部类对象,而不能直接去 new 一个内部类对象,即:内部类 对象名 = 外部类对象.new 内部类( );
  4. 编译上面的程序后,会发现产生了两个 .class 文件
    分别是Outter.class和 Outter$Inner.class
  5. 外部类不能直接使用内部类的成员变量和方法,可以先构造内部类对象,在使用其成员变量
  6. 如果外部类和内部类具有相同的成员变量或方法,内部类默认访问自己的成员变量或方法,如果要访问外部类的成员变量,可以使用 this 关键字

二,静态内部类

public class Soutter {

private static int a = 100;
private static int b =1;
private int c = 1100;
public void outMethod() {
System.out.println("外部类方法");
}
public static void sOutMethod() {
System.out.println("外部类静态方法");
}

public static class Sinner{

private int a = 10;

private static int b = 102;

private void sInnerMethod() {
// 静态内部类不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问
System.out.println("内部类静态方法访问外部类的非静态成员"+new Soutter().a);
// 如果外部类的静态成员与内部类的成员名称相同,可通过“类名.静态成员”访问外部类的静态成员;
System.out.println("内部类静态方法访问外部类的静态成员"+Soutter.b);
// 如果外部类的静态成员与内部类的成员名称不相同,则可通过“成员名”直接调用外部类的静态成员。
System.out.println("内部类静态方法访问外部类的静态成员"+a);
}

}

// 测试
public static void main(String[] args) {

// 创建静态内部类的对象时,不需要外部类的对象,可以直接创建 内部类 对象名= new 内部类();
Sinner sinner = new Sinner();
sinner.sInnerMethod();
}

}

总结:

  1. 静态内部类不能直接访问外部类的费静态成员,但可以通过 new 外部类().成员 的方式访问
  2. 如果外部类的静态成员与内部类的成员名称相同,可通过“类名.静态成员”访问外部类的静态成员;如果外部类的静态成员与内部类的成员名称不相同,则可通过“成员名”直接调用外部类的静态成员。
    三,方法内部类
public class Moutter {

private int a=100;

private static int b=90;

public void show() {

int a = 80;
class Minner{

public void mmethod() {
System.out.println("方法内部类使用外部类的成员变量:"+new Moutter().a);
System.out.println("方法内部类使用外部类方法的局部变量:"+b);
}
}

// 方法内部类就是内部类定义在外部类的方法中,方法内部类只在该方法的内部可见,即只在该方法内可以使用
Minner minner = new Minner();
minner.mmethod();
// 由于方法内部类不能在外部类的方法以外的地方使用,因此方法内部类不能使用访问控制符和 static 修饰符。
}

public static void main(String[] args) {

Moutter outter = new Moutter();
outter.show();
}
}

总结:

  1. 方法内部类只在该方法的内部可见,即只在该方法内可以使用。
  2. 方法内部类不能在外部类的方法以外的地方使用,因此方法内部类不能使用访问控制符和 static 修饰符。

四,匿名内部类
1、使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口。

2、匿名内部类中是不能定义构造函数的。

3、匿名内部类中不能存在任何的静态成员变量和静态方法。

4、匿名内部类为局部内部类(即方法内部类),所以局部内部类的所有限制同样对匿名内部类生效。

5、匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。
6. 如果是在一个方法的匿名内部类,可以利用这个方法传进你想要的参数,不过记住,这些参数必须被声明为 final(拷贝引用,为了避免引用值发生改变,例如被外部类的方法修改等,而导致内部类得到的值不一致,于是用final来让该引用不可改变。)