在一个类内部定义的类称为内部类,初学者而言,内部类似乎有点多余,其实不然。
顶层类只能属于public和默认访问级别,而成员内部类可以处于public、protected、private和默认四种访问级别。
1.实例内部类
package demo12_1;
public class Outer {
public class InnerTool{ //实例内部类
public int add(int a,int b){
return a+b;
}
}
private InnerTool tool=new InnerTool();
public void add(int a,int b,int c){
tool.add(tool.add(a, b),c);
}
}
package demo12_1;
import demo12_1.Outer.InnerTool;
public class Tester {
public static void main(String[] args) {
Outer o=new Outer();
o.add(1, 2, 3);
//创建实例内部类的实例
Outer.InnerTool outer=new Outer().new InnerTool();
//等价于
/*Outer outer=new Outer();
Outer.InnerTool tool=outer.new InnerTool();*/
}
}
实例内部类有以下特点:
(1)在创建实例内部类的时候,外部类的实例必须已经存在,如上new Outer().new InnerTool();
(2)实例内部类的实例自动持有外部类的实例的引用,在内部类,可以直接访问外部类的所有成员,包括成员变量,成员方法。
(3)外部类的实例和内部类实例之间是一对多的关系,一个内部类实例只会引用一个外部类实例,而一个外部类实例对应零或多个内部类实例。在外部类中不能直接访问内部类的成员,必须通过内部类的实例去访问。
(4)在实例内部类中不能定义静态成员,而只能定义实例成员。
(5)如果在实例内部类B与外部类A包含同名的成员,那么在类B中,this.v表示B的成员A.this.v表示A的成员。
2、静态内部类
静态内部类时成员内部类的一种,用static修饰符修饰。
(1)静态内部类实例不会自动持有外部类的特定实例的引用,在创建内部类的实例时,不必创建外部类的实例。
public class ClassA {
int b;
public static class B{
int c=new ClassA().b;
int v;
}
}
public class Tester {
public void test(){
ClassA.B b=new ClassA.B();
}
}
(2)静态内部类可以直接访问外部类静态成员,如果访问外部类实例成员,就必须通过外部类的实例去访问。
(3)在静态内部类中可以定义静态成员和实例成员。
(4)客户类可以通过完整的类名直接访问静态内部类的静态成员。
3.局部内部类
局部内部类是在一个方法中定义的类,它的可见范围是当前方法。和局部变量一样,局部内部类不能用public private和protected以及static修饰符修饰。
(1)局部内部类只能在当前方法中使用。
(2)局部内部类和实例内部类一样,不能包含静态成员。
(3)在局部内部类中定义的内部类也不能被public protected和private这些访问控制修饰符修饰。
(4)局部内部类和实例内部类一样,可以访问外部类的所有成员,此外,局部内部类还可以访问所在方法中的final类型的参数和变量:
public void method(final int p1,int p2){ int localV1=1; final int localV2=2; class B{ int b1=p1; //int b2=p2; //编译错误 //int b3=localV1; //编译错误 int b4=localV2; } }