话不多说直接走起
1.怎么直接在外部 创建 内部类呢?
public class Demo { public static void main(String[] args) { Outer.Inner in=new Outer().new Inner(); in.show(); } } class Outer{ int a=3; public class Inner{ void show() { System.out.println("a="+a); } } public void method() { new Inner().show(); } }
要创建 Inner 对象 需要先创建 Outer 对象 因为 Inner类相当于是作为 Outer 类的一个属性存在
然后再创建内部对象。这样写可能比较奇怪,然而它就是需要这样创建的。
内部类可以直接使用 外部类的属性或者方法的,不管外部类属性和方法的权限是什么。
2.静态内部类的创建
public class Demo { public static void main(String[] args) { Outer.Inner in=new Outer.Inner(); in.show(); } } class Outer{ private static int a=3; public static class Inner{ void show() { System.out.println("a="+a); } } public void method() { new Inner().show(); } }
此时静态内部类相当于作为外部类的静态属性存在,他是随着外部类的加载而加载的
3.非静态内部类不能定义非静态的属性或者方法
public class Demo { public static void main(String[] args) { Outer.Inner.show(); } } class Outer{ private static int a=3; class Inner{ static void show() { System.out.println("a="+a); } } public void method() { new Inner().show(); } }
如上 Inner 类 里面是不能成功定义 show 方法的
这是为什么呢?
因为此时内部类Inner相当于是作为 外部类的 成员属性存在的
假如我们可以定义成功。
只有 创建Outer实例的时候 内部类才会进行加载。
而如果我们直接这样 Outer.Inner.show(); 调用内部类的静态方法的时候
此时因为没有 创建 Outer 对象 所以内部类 Inner 在内存中是不存在的,
更别说是这个类里面的方法了,所以非静态内部类是不能定义静态方法或者属性的。
但是 如果定义的变量是 final 的,这是可以的。
public class Demo { public static void main(String[] args) { new Outer().new Inner().show(); } } class Outer{ private static int a=3; class Inner{ static final int b=4; void show() { System.out.println("a="+a); } } public void method() { new Inner().show(); } }
上述 内部类中的变量 b 是可以定义成功的。
这又是为什么呢?
因为我们看到的是 定义了一个常量,然后用常量,打印的时候,打印这个常量,
但是真实是在编译完成之后,里面使用到的常量是直接替换成对应的值得,
所以,以下 对应的地方是直接替换成 数字 4 而不是常量对应的数字 4
void show() { System.out.println("a="+4); }
我们这样书写,只是为了代码的可读性而已。
4.内部类的继承
public class Demo { public static void main(String[] args) { Outer outer=new Outer(); outer.method(); } } interface Father{ void show(); } class Outer{ private class Inner implements Father{ static final int b=4; public void show() { System.out.println("a="+b); } } public void method() { Inner aFather= new Inner(); aFather.show(); } }
5.内部类继承的简化形式 (匿名内部类)
如果只是用到了 接口中的方法,根本就不需要创建子类对象的引用,只需要引用父类就可以了
public class Demo { public static void main(String[] args) { Outer outer=new Outer(); outer.method(); } } interface Father{ void show(); } class Outer{ private class Inner implements Father{ static final int b=4; public void show() { System.out.println("a="+b); } } public void method() { Father aFather= new Inner(); aFather.show(); } }
可以进一步简化,内部类的名字已经没有意义了
public class Demo { public static void main(String[] args) { Outer outer=new Outer(); outer.method(); } } interface Father{ void show(); } class Outer{ public void method() { Father aFather= new Father() { static final int b=4; public void show() { System.out.println("a="+b); } }; aFather.show(); } }
这就是匿名内部类的使用
如果接口里面的方法只有一个的话,而且只调用一次的话,完全可以进一步简化(可以使用匿名对象)
public class Demo { public static void main(String[] args) { Outer outer=new Outer(); outer.method(); } } interface Father{ void show(); } class Outer{ public void method() { new Father() { static final int b=4; public void show() { System.out.println("a="+b); } }.show(); } }
提醒:
内部类的定义就是为了控制他的访问权限的,一般定义内部类就是为了不让
外部对他进行访问的,所以最好使用 private 来修饰内部类。