一、概念
在某个类中,嵌套定义的类 - 类中类
- 内部类是指在一个外部类的内部再定义一个类
- 内部类作为外部类的一个成员,并且依附于外部类而存在的
- 内部类可为静态,可用 protected 和 private 修饰。而外部类不可以,外部类只能使用 public 和 default 修饰
1 2 3 4 5 6 7 8 9 10 11 12 | [访问修饰符] class 类名 { // 1.成员变量 // 2.成员方法 // 3.常量 // 4.构造方法 // 5.静态方法 // 6.重写方法 // 7.重载方法 // 8.类 - 成员内部类 } |
二、作用
- 使用内部类可以使程序更加的简洁,便于命名规范和划分层次结构,提供了更好的封装性,除了所在的外部类,其他类都不能访问。
- 使用内部类最大的优点就在于它能够非常好的解决多重继承的问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public interface Father { } public interface Mother { } public class Son implements Father, Mother { } public class Daughter implements Father{ class Mother_ implements Mother{ } } |
其实对于以上实例我们确实是看不出来使用内部类存在何种优点,但是如果Father、Mother不是接口,而是抽象类或者具体类呢?这个时候我们就只能使用内部类才能实现多重继承了。
在我们程序设计中有时候会存在一些使用接口很难解决的问题,这个时候我们可以利用内部类提供的、可以继承多个具体的或者抽象的类的能力来解决这些程序设计问题。可以这样说,接口只是解决了部分问题,而内部类使得多重继承的解决方案变得更加完整。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | public class Father { public void f() { } } public class Mother { public void m() { } } public class Son extends Father { /** * 成员内部类 - 这里相当于同时继承了 Father 类和 Mother 类 * <p> * 因此,在内部类中,可以同时访问 Father 类和 Mother 类的成员 */ class SonFatherMother extends Mother { public void aa() { m(); f(); } } public void bb() { super.f(); } } |
四、分类
- 成员内部类
- 静态内部类
- 局部内部类
- 匿名内部类
五、实现
1、成员内部类
与成员变量、成员方法类似,作为某个类的成员定义的类,叫成员内部类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | //定义外部类 - 外部类修饰符只能为:public 或 default(缺省) [访问修饰符] class Outer { // 1.外部类成员 protected int age ; // 2.成员内部类 // 修饰符可以为:与类成员一样,都可以使用四个修饰符 [访问修饰符] class 内部类名 { // 3.内部类成员 } [访问修饰符] 数据类型 方法名([参数列表]) { 内部类名 对象 = new 内部类名() ; 对象.成员... } } |
实例化对象
1 2 3 4 5 6 | // 语法一 外部类 外部类对象 = new 外部类() ; 外部类名称.内部类名称 内部类对象 = 外部类对象.new 内部类名称() ; // 语法二 外部类名称.内部类名称 内部类对象 = new 外部类名称().new 内部类名称() ; |
2、静态内部类
与静态变量、静态方法类似,作为某个类的静态成员定义的类,叫成员内部类
1 2 3 4 5 6 7 8 9 | // 定义外部类 class Outer { // 1.外部类成员 // 2.成员内部类 [访问修饰符] static class 内部类名 { // 3.内部类成员 - 注意:静态内部类不能访问非静态成员 } } |
实例化对象
1 2 | // 语法 外部类.内部类 内部类对象 = new 外部类.内部类() ; |
3、局部内部类
与局部变量类似,在方法内定义的类称为局部内部类;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | class Outer { // 1.外部类成员 // 2.成员方法 [访问修饰符] 数据类型 方法名([参数列表]) { // 3.局部内部类 class 内部类名 { // 4.内部类成员 } // 5.创建局部内部类对象: // 局部内部类名 对象 = new 局部内部类名() ; // 6.调用属性或方法 } } |
4、匿名内部类
匿名内部类是一种特殊的局部内部类,它是通过匿名类实现接口。
1 2 3 4 5 6 7 8 9 10 | new 外部类().方法(new 接口|抽象类|父类(){ 接口方法的实现(); 或 重写抽象类或父类的方法() ; }) ; 接口名称 对象名 = new 接口名称() { 重写抽象方法; } |