1.静态内部类
类中的嵌套类前面加static,也叫嵌套顶级类
(1)该类属于类的静态成员,与具体的对象实例无关;
(2)该类的成员方法可以直接访问其顶级类的所有静态成员,但不能访问非静态成员,会出错;
(3)在顶级类中,可直接声明并创建其嵌套顶级类的对象实例;其他类中:顶级类名.嵌套顶级类名 嵌套顶级类对象=new 顶级类名.嵌套顶级类名();Outer.Inner in = new Outer.Inner();
(4)非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围类,但是静态内部类却没有。说明静态内部类的创建是不需要依赖于外围类,可以直接创建。静态内部类不可以使用任何外围类的非static成员变量和方法,而内部类则都可以,比如访问私有属性
class Outer4 {
private static String name = "pp";
static class Inner {
public void fun() {
System.out.println(name);
}
}
}
public class StaticClass {
public static void main(String[] args) {
Outer4.Inner in = new Outer4.Inner();
in.fun();
}
}
2.实例内部类
类中的嵌套类前面没有加static
(1)实例内部类的成员方法可以访问其顶级类的所有成员,非静态、静态、private;
(2)在顶级类中,可直接声明并创建其实例内部类的对象实例(传入this);其他类中:顶级类名.实例内部类名 实例内部类对象=new 实例内部类名.实例内部类名();
3.方法内部类
(1)在方法体的代码中声明,和局部变量位于同一级别
(2)方法内部类除了可以访问顶级类的静态成员和实例成员,还可以访问所在方法中的局部变量和方法参数,访问方法参数时,该形参必须是final修饰(JDK1.8变为隐式final声明)
(3)方法内部类只能在该方法中被使用,出了该方法就会失效。
(4)局部类的前面不能加访问修饰符,private等
(5)局部内部类对外隐藏,只有创建这个类的方法可以访问
class Outter {
private int num;
//创建该类的方法可以访问
public void display(int test) {
class Inner {
private void fun() {
num++;
System.out.println(num);
System.out.println(test);
}
}
new Inner().fun();
}
}
4.匿名内部类
就是一个没有名字的方法内部类
- 匿名内部类是没有访问修饰符的,在方法的内部,外部类不能访问。
- 匿名内部类必须继承一个父类或者实现一个接口
- 匿名内部类中不能存在任何静态成员或方法
- 匿名内部类是没有构造方法的,因为它没有类名。
- 与局部内部相同匿名内部类也可以引用方法形参。此形参也必须声明为 final
interface I {
void test();
}
class Outer5 {
//实现接口
public void display() {
new I() {
@Override
public void test() {
System.out.println("匿名内部类");
}
}.test();//如果不写test()的话没有输出语句
}
}
public class NONameClass {
public static void main(String[] args) {
Outer5 outer5 = new Outer5();
outer5.display();
}
}
5.成员内部类
- 成员内部类中不能存在任何static的变量和方法
- 成员内部类是依附于外围类的,访问成员内部类时先创建外围类的引用,再实例化内部类的对象
public class Test{
public Test(){
System.out.println("这是一个类");
}
public static void main(String[] args) {
new Test();
new Test().new Test1().test();
}
class Test1{
public void test(){
System.out.println("这是一个成员内部类");
}
}
- Test1在Test类中,像Test1的成员,故Test1是成员内部类,可以访问外部类的所有成员属性和成员方法,包括私有的和静态的
- 当成员内部类和外部类具有同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员
外部类.this.成员变量 外部类.this.成员方法
6.内部类和外部类的区别
- 对于非静态内部类,内部类的创建依赖外部类的实例对象,在没有外部类实例之前是无法创建内部类的
- 内部类是一个相对独立的实体,与外部类不是is-a关系
- 内部类可以直接访问外部类的元素(包含私有域),但是外部类不可以直接访问内部类的元素
- 外部类可以通过内部类引用间接访问内部类元素
class Outter {
//外部类访问内部类元素,需要通过内部类引用来访问
public void display() {
Inner inner = new Inner();
inner.display();
}
class Inner {
public void display() {
System.out.println("I am InnerClass");
}
}
}
public class Test {
public static void main(String[] args) {
Outter out = new Outter();
out.display();
}
}
(1)在外部类外部创建内部类
外部类.内部类 内部类对象 = new 外部类().new 内部类();
Outter.Inner in = new Outter().new Inner();
(2)在外部类内部创建内部类,就像普通对象一样直接创建
Inner in = new Inner();