Java中内部类使用场景:
1、隐藏实现
当一个类单独出现的时候,是不能以private,protected关键字修饰的,但是作为内部类出现的时候,是可以加这类关键字修饰,所以,内部类第一个作用,就是隐藏实现,参见代码:
public interface InterfaceA{ public void f(); } public class InnerClassExam1{ private class InnerClass implements InterfaceA{ public void f(){ System.out.println("InnerClass.f()"); } } public InterfaceA getInterfaceA(){ return new InnerClass(); } }
测试代码:
public class InnerClassTest1{ public static void main(String[] args){ InnerClassExam1 exam1 = new InnerClassExam1(); InterfaceA inter = exam1.getInterfaceA(); inter.f(); } }
2、内部类可以访问外围类的所有变量
一个类的内部类可以访问外围类的所有成员变量,包括private修饰符修饰的变量,代码如下:
public class InnerClassExam2{ private String outer = "outer"; private class InnerClass implements InterfaceA{ public void f(){ System.out.println(outer); } } public InterfaceA getInterfaceA(){ return new InnerClass(); } }
测试代码:
public class InnerClassTest2{ public static void main(String[] args){ InnerClassExam2 exam = new InnerClassExam2(); InterfaceA inter = exam.getInterfaceA(); inter.f(); } }
3、内部类实现多重继承
实现多重继承,应该算是Java中内部类最重要的作用之一,在不使用内部类的情况下,只能通过实现多个接口来实现多重继承,但是,实现接口,就必须实现其所有的声明方法,虽然可以通过抽象类来实现,但是这样又加了一层继承体系,所以,使用内部类实现多重继承可以规避这些问题,这样设计更加优雅。
接口代码:
public interface InterfaceB{ public BaseClass1 getBaseClass1(); public BaseClass2 getBaseClass2(); }
基类代码:
public class BaseClass1{ public BaseClass1(){ System.out.println("BaseClass1"); } public void f(){ System.out.println("BaseClass1.f()"); } } public class BaseClass2{ public BaseClass2(){ System.out.println("BaseClass2"); } public void f(){ System.out.println("BaseClass2.f()"); } }
内部类实现多重继承代码:
public class InnerClassExam3 implements InterfaceB{ private class InnerClass1 extends BaseClass1{ public InnerClass1(){ System.out.println("InnerClassExam3.InnerClass1"); } } private class InnerClass2 extends BaseClass2{ public InnerClass2(){ System.out.println("InnerClassExam3.InnerClass2"); } } public BaseClass1 getBaseClass1(){ return new InnerClass1(); } public BaseClass2 getBaseClass2(){ return new InnerClass2(); } }
测试代码:
public class InnerClassTest3{ public static void main(String[] args){ InterfaceB inter = new InnerClassExam3(); BaseClass1 baseClass1 = inter.getBaseClass1(); BaseClass2 baseClass2 = inter.getBaseClass2(); baseClass1.f(); baseClass2.f(); } }
从代码中,可以看出,InnerClassExam3实现了一个接口,继承了两个类(应该说具备了两个类的能力)BaseClass1,BaseClass2,同时继承BaseClass1和BaseClass2的两个内部类InnerClass1和InnerClass2又隐藏了对外的实现,所以可以理解为InnerClassExam3实现了多重继承。
4、语法限制
有些时候,由于语法限制,必须使用内部类来解决一类问题,比如一个类需要同时实现一个接口和继承一个类(或者同时实现多个含有相同方法签名的接口),但是这个接口和需要继承的基类中有相同的方法签名,这个时候,就需要引入内部类,以规避方法签名冲突,但是这样做也有一个问题,失去了部分向上转型的多态特性,代码:
接口:
public interface InterfaceA{ public void f(); } public interface InterfaceC{ public void f(); }
基类:
public abstract class BaseClass3{ public abstract void f(); }
内部类代码:
public class InnerClassExam4 implements InterfaceC{ private class InnerClass1 implements InterfaceA{ public void f(){ System.out.println("InterfaceA.f()"); } } private class InnerClass2 extends BaseClass3{ public void f(){ System.out.println("BaseClass3.f()"); } } public void f(){ System.out.println("InterfaceC.f()"); } public InterfaceA getInterfaceA(){ return new InnerClass1(); } public BaseClass3 getBaseClass3(){ return new InnerClass2(); } }
测试代码:
public class InnerClassTest4{ public static void main(String[] args){ InterfaceC exam = new InnerClassExam4(); exam.f(); InterfaceA interA = ((InnerClassExam4)exam).getInterfaceA(); interA.f(); BaseClass3 baseClass3 = ((InnerClassExam4)exam).getBaseClass3(); baseClass3.f(); } }
运行结果:
InterfaceC.f()
InterfaceA.f()
BaseClass3.f()
可以看出,InnerClassExam4实现了接口InterfaceC,并实现InterfaceC的声明方法f(),内部类InnerClass1实现接口InterfaceA,并实现InterfaceA的声明方法f(),内部类InnerClass2继承抽象类BaseClass3,并实现抽象方法f(),其中InterfaceC,InterfaceA,BaseClass3中的方法f()签名相同,所以,这里使用内部类规避方法签名冲突。