内部类就是在一个类A的定义内部定义的类B,类B可以跟类A的成员变量/方法同级,也可以定义在类A的方法中,等等。内部类一般包括这四种:成员内部类、静态内部类、局部内部类和匿名内部类。
每个内部类都能独立地实现一个接口或者抽象类,所以无论其所属的主类是否已经实现一个接口或者抽象类,对于内部类都没有影响。如果没有内部类提供的可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。从这个角度看,内部类采可以实现多重继承的效果。
成员内部类和静态内部类用private/protected/public修饰时,外部访问规则与访问对应外部类的属性/方法的规则一样;局部内部类不能使用访问修饰符修饰;匿名内部类甚至都不用class关键字来定义,下面是这几种内部类的举例说明:
1、成员内部类
public class OuterClass1 { private String name = "OuterClass"; private static int age = 25; public static void main(String[] args) { OuterClass1 outerClass = new OuterClass1(); InnerClass innerClass = outerClass.new InnerClass(); //访问成员内部类需要用对应主类的对象进行访问 innerClass.innerPrint(); } public OuterClass1() { System.out.println("OuterClass init……"); } public void print() { System.out.println("OuterClass print()"); } protected class InnerClass { //private static String name="InnerClass"; //局部内部类不能定义静态变量/方法(Inner classes cannot have static declarations) private String name = "InnerClass"; //局部内部类可以定义对应主类属性相同的变量 public InnerClass() { System.out.println("InnerClass init……"); } public void print() { System.out.println("InnerClass print()"); } public void innerPrint() { System.out.println("name of InnerClass:" + name); //内部类引用自己的变量 System.out.println("name of InnerClass:" + this.name); //内部类引用自己的变量 System.out.println("name of OuterClass:" + OuterClass1.this.name); //内部类引用对应主类的同名变量 System.out.println("age of OuterClass:" + age); //内部类引用对应主类的变量 System.out.println("age of OuterClass:" + OuterClass1.age); //内部类引用对应主类的变量 print(); //内部类调用自己与主类同名的方法 OuterClass1.this.print(); //内部类调用对应主类的同名方法 } } }
(1)成员内部类对象中不能定义静态变量、静态方法
(2)要创建成员内部类对象,必须要先创建对应外部类的对象
(3)成员内部类引用对应主类的同名属性/方法时,格式为:主类名.this.属性名/方法名
2、静态内部类
public class OuterClass { private String name = "OuterClass"; private static int age = 25; public static void main(String[] args) { OuterClass outerClass = new OuterClass(); OuterClass.InnerClass innerClass = new OuterClass.InnerClass();//可以直接通过对应主类访问静态内部类 } public OuterClass() { System.out.println("OuterClass Init……"); } protected static class InnerClass { private static String name = "InnerClass"; //静态内部类可以定义对应主类属性相同的变量;可以定义静态变量 private static int age = 25; public InnerClass() { System.out.println("InnerClass Init……"); } } }
(1)要创建嵌套类的对象,并不需要其外围类的对象。
(2)不能从嵌套类的对象中访问非静态的外围类对象。
3、局部内部类
public class OuterClass { private String name = "OuterClass"; private static int age = 25; public static void main(String[] args) { OuterClass outerClass = new OuterClass(); outerClass.addAgeForInnerClass(); } public void addAgeForInnerClass() { final int addAge = 1; class InnerClass { String name = "InnerClass"; int age = 20; public void addAge(int age) { this.age += age; System.out.println("age of InnerClass:" + this.age); } public void print() { System.out.println("name of InnerClass:" + name); //内部类引用自己的变量 System.out.println("name of InnerClass:" + this.name); //内部类引用自己的变量 System.out.println("name of OuterClass:" + OuterClass3.this.name); //内部类引用对应主类的同名变量 System.out.println("age of InnerClass.addAgeForInnerClass.addAge:" + addAge);//内部类引用所在方法中的变量 } } InnerClass innerClass = new InnerClass(); innerClass.addAge(addAge); } }
(1)局部内部类可以定义在静态代码块、构造代码块、方法中
(2)局部内部类不可以用访问修饰符(private/protected/public)修饰
4、匿名内部类
匿名内部类也是一种局部内部类,不需要用class关键字来声明,匿名内部类通常是一个抽象类或接口的实现(二者只能选择其一),直接通过new关键字来实例化。
public abstract class AbstractClass { protected static String name = "Danny"; protected static int age = 25; public abstract void print(); } public class OuterClass { public static void main(String[] args) { print(178); } public static void print(final int height) { AbstractClass abstractClass = new AbstractClass() { @Override public void print() { System.out.println(name + "' age is " + age + ",his height is" + height); } }; abstractClass.print(); } }
(1)匿名内部类中不能定义静态变量/方法
(2)匿名内部类中不能定义构造函数
(3)匿名内部类中引用的外界变量必须为final