本文参考自
mike11:https://www.cnblogs.com/uu5666/p/8185061.html
首先明确什么是内部类:放在类内部的类称为内部类。它主要有以下4个作用:
1)内部类可以很好地实现隐藏
一般非内部类,是不允许有private与protected权限的,但内部类可以。
2)内部类拥有外部类的所有元素的访问权限
3)可以实现多重继承
4)可以避免修改接口而实现同一个类中两种同名方法的调用
举例说明:
1)实现隐藏
一般我们对类的访问权限,都是通过类前面的访问修饰符来限制的,非内部类和内部类有着很大不同。如:
/** * 接口 */ public interface TestInterface { void show(); }
/** * 实现类 */ public class TestExample { /** * 内部类 访问权限修饰符可以是private、protected */ private class InsideClassI implements TestInterface{ @Override public void show() { System.out.println("内部类的作用之private修饰"); } } protected class InsideClassII implements TestInterface{ @Override public void show() { System.out.println("内部类的作用之protected修饰"); } } /** * 获取内部类方法 */ public TestInterface getInsideClass(){ return new InsideClassI(); } }
/** * 测试类 */ public class Test { public static void main(String[] args) { TestExample example = new TestExample(); TestInterface insideClass = example.getInsideClass(); insideClass.show(); } }
通过TestExample的getInsideClass()方法可以得到一个TestInterface的实例,但是并不知道这个实例的实现过程,由于insideClass是private修饰的,如果不看代码也不能知道这个具体类的名字,因此内部类实现了很好的隐藏。
2)可以无条件地访问外部元素
/** * 定义一个类 */ public class Person { private String name; private Integer age; private char gender; /** * 内部类 */ private class Student{ public Student(){ System.out.println(name); } } /** * 普通方法 */ public void show(){ new Student(); } public static void main(String[] args) { Person p = new Person(); p.show(); } }
name变量在Person类中定义且是私有的,但是内部类Student可以直接访问,不需要条件。
3)可以实现多重继承
这是内部类最大的特点,它使Java继承机制更加完善。因为Java是单继承的,多重继承在没有内部类之前是通过接口来实现的,但使用接口有许多限制的地方,比如实现一个接口就必须实现它里面的所有方法,而内部类就不同了,它可以使我们的类继承多个具体类或抽象类。
/** * 样类1 */ public class Example1 { public String name(){ return "zhangsan"; } }
/** * 样类2 */ public class Example2 { public int age(){ return 26; } }
/** * 样类3 */ public class ExampleMain { /** * 内部类test1 */ private class test1 extends Example1{ public String name(){ return super.name(); } } /** * 内部类test2 */ private class test2 extends Example2{ public int age(){ return super.age(); } } public String name(){ return new test1().name(); } public int age(){ return new test2().age(); } public static void main(String[] args) { ExampleMain em = new ExampleMain(); System.out.println("姓名:"+em.name()); System.out.println("年龄:"+em.age()); } }
测试结果:
从上述事例中可以看到,样类3中的两个内部类使得样类3拥有了样类1和样类2的属性和方法,即间接实现了多继承。
4)避免修改接口而实现同一个类中两种同名方法的调用。
当一个类要继承一个类并实现一个接口时,但是要继承的类和要实现的接口中存在同名的方法,这时候如何去区分?内部类可以解决这种问题。
/** * 样类1 */ public class Example1 { public String name(){ return "zhangsan"; } void show(){ } }
/** * 接口 */ public interface TestInterface { void show(); }
/** * 样类2 */ public class Example2 extends Example1 { public int age(){ return 26; } private class InnerClass implements TestInterface{ @Override public void show() { } } TestInterface getInnerClass(){ return new InnerClass(); } }
样类2使用内部类实现接口,避免了与外部类的方法重名的冲突。