内部类就是在一个类内部进行其他类结构的嵌套操作,这样设计的目的在于将某些特殊用途的类进行封装,比如B类只是给A类使用,那么我们将B类定义为A类的内部类,整体的代码逻辑就十分简洁。
内部类一样可以使用权限修饰符,public、private、protected都可以使用。
1. 普通内部类
普通内部类是无法在当前类以外的地方进行直接实例化,下面示例中在主函数程序中直接使用new Inner();是错误的,如果非要使用可以采用new Outter().new Inner();这样的方式:
public class Outter {public Outter() {System.out.println("Outter");}public class Inner {public Inner() {System.out.println("Inner");}}public void printInner() {new Inner();}public static void main(String[] args) {new Outter();new Outter().printInner();}}
代码成功编译后,会产生两个文件 Outter$Inner.class 和 Outter.class,可以明显地看出这是两个类文件,这也表明了不会在同一加载流程中:
❯ ls -laOutter$Inner.class Outter.class
2. 静态内部类
显然new Outter().new Inner();这样的调用方式太反人类了,我们期望使用方式类似new Outter.Inner();,这种调用格式与之前的静态方法很一致,称之为静态内部类:
public class Outter {public Outter() {System.out.println("Outter");}public static class Inner {public Inner() {System.out.println("Inner");}}public void printInner() {new Inner();}public static void main(String[] args) {new Outter.Inner();}}
💡 注意点 —————
- 静态内部类只会在第一次实例化时才会加载一次,否则不会加载。
- 类内部的属性和方法如果不加
static的话,它就是属于实例对象的。
3. 匿名内部类
匿名内部类可以让代码更加简洁,我们可以在定义一个类时同时实例化。它与局部类很相似,不同的是它没有类名,如果某个局部类我们只使用一次,那么匿名内部类就非常适合使用。
匿名类是一个表达式,语法就类似于调用一个类的构造函数(new HelloWorld()),并包含了一个完善类定义的 代码块:
| ```java wolf.eat(new Animal() { @Override public void eat(Animal animal) { System.out.println(this.getName()
+ "likes eating " + animal.getName());}@Overridepublic String getName() {return "sheep";}
});
| ```javatigger.eat(new Wolf() {@Overridepublic void eat(Animal animal) {super.eat(animal);}@Overridepublic String getName() {return "wolf";}});
| | —- | —- |
