1.为什么要使用内部类
采用内部类,可以更好地隐藏细节和内部结构,封装性更好,让程序的结构更加合理;
如果不用内部类,每个类都单独作为一个类,类的种类太多,调用起来麻烦;
1.非静态内部类
package InnerClassTest;/*** ClassName:OuterClass* Package:InnerClassTest* Description:** @Date:2021/8/30 13:13* @Author:zhanglei@3417529439@qq.com*/public class OuterClass {private String outerName;public OuterClass(){outerName="outerClassName";}public void display(){System.out.println("OuterClass Display");System.out.println(outerName);}//只有先new出来外部类的对象才能访问非静态内部类public class InnerClass{private String innerName;public InnerClass(){innerName="innerClassName";}public void display(){System.out.println("InnerClass Display");System.out.println(innerName);}}public static void main(String[] args) {OuterClass outerClass=new OuterClass();outerClass.display();// InnerClass innerClass = new InnerClass(); //这样没法编译通过InnerClass innerClass = outerClass.new InnerClass();//非静态内部类的创建需要借助外部类的对象才能创建innerClass.display();}}OuterClass DisplayouterClassNameInnerClass DisplayinnerClassName
注意一个点:
对于非静态内部类,必须先有外部类的对象才能生成内部类的对象
使用1(在外部类中调用内部类):
OuterClass outerClass=new OuterClass();
InnerClass innerClass = outerClass.new InnerClass();
使用2(在其他类中调用内部类):
public class Test1 {
public static void main(String[] args) {
OuterClass.InnerClass i1=new OuterClass().new InnerClass();
i1.display();
}
}
1.1 少见的局部内部类

2.静态内部类
package InnerClassTest;/*** ClassName:OuterClass* Package:InnerClassTest* Description:** @Date:2021/8/30 13:13* @Author:zhanglei@3417529439@qq.com*/public class OuterClass {private String outerName;public OuterClass(){outerName="outerClassName";}public void display(){System.out.println("OuterClass Display");System.out.println(outerName);}//可以直接访问静态内部类,无需先new出外部类的对象public static class InnerClass{private String innerName;public InnerClass(){innerName="innerClassName";}public void display(){System.out.println("InnerClass Display");System.out.println(innerName);}}public static void main(String[] args) {OuterClass outerClass=new OuterClass();outerClass.display();InnerClass innerClass = new InnerClass();innerClass.display();}}
使用1:在外部类中调用内部类
InnerClass innerClass = new InnerClass();
使用2:在其他类中调用内部类
public class Test1 {
public static void main(String[] args) {
OuterClass.InnerClass i1=new OuterClass.InnerClass();
i1.display();
}
}
注意new OuterClass.InnerClass()和new OuterClass().InnerClass();的区别
前者是OuterClass.InnerClass作为一个整体
后者是OuterClass和InnerClass各自作为一个整体
3.匿名内部类
1.先定义一个接口
public interface MyInterface {
public void test();
}
2.传统方法:定义一个类去继承该接口,实现test方法
public class MyImplements implements MyInterface{
@Override
public void test() {
System.out.println(“test!”);
}
}
3.匿名内部类:不显式定义一个类去继承该接口,而是直接new
public class AnonymousTest {public static void main(String[] args) {//传统方法MyInterface myImplements = new MyImplements();myImplements.test();//匿名内部类直接使用new MyInterface(){@Overridepublic void test() {System.out.println("大家好");}}.test();//匿名内部类赋值给一个引用变量再使用MyInterface myInterface=new MyInterface(){@Overridepublic void test() {System.out.println("我是VAE");}};myInterface.test();}}test!大家好我是VAE
匿名内部类:
匿名:没有显式定义一个类该实现接口
内部类:确实是类的内部定义的
易混淆点:
匿名内部类容易跟lambda表达式联系在一起;
lambda表达式要求对应的接口只有一个抽象方法(继承Object的抽象方法不考虑),
那匿名内部类的接口是否也是只能有一个抽象方法,答案是否定的
public interface MyInterface {public void test();public void test1();}
public class MyImplements implements MyInterface{@Overridepublic void test() {System.out.println("test!");}@Overridepublic void test1() {System.out.println("test1!");}}
public class AnonymousTest {public static void main(String[] args) {MyInterface myImplements = new MyImplements();myImplements.test1();new MyInterface(){@Overridepublic void test() {System.out.println("大家好");}@Overridepublic void test1() {System.out.println("你好");}}.test1();MyInterface myInterface=new MyInterface(){@Overridepublic void test() {System.out.println("我是VAE");}@Overridepublic void test1() {System.out.println("你是qq");}};myInterface.test1();}}test1!你好你是qq
匿名内部类要实现的接口有多少抽象方法就实现多少抽象方法
