什么是嵌套类以及内部类 ?
可以在一个类的内部类定义另一个类,这种类称为嵌套类,它有两种类型 :
静态嵌套类和非静态嵌套类;非静态嵌套类使用比较多,也称作为内部类(inner),其中内部类(inner)类又分为三种 :
1.)在一个类(外部类)中直接定义的内部类;
2.)在一个方法(外部类的方法)中定义的内部类;
3.)匿名内部类。
一 : 静态嵌套类 :
public class StaticTest{
private static String name = "hello world";
private String num = "ABC";
static class Person{
private static address = "Java";
public String mall = "China"; //内部类公有成员
public void display(){
//System.out.println(num); //不能直接访问外部类的非静态成员
System.out.println(name); //只能直接访问外部类的静态成员
System.out.println("Inner"+address); //访问本内部类成员
}
}
public void printlnFo(){
Person person = new Person();
person.display();
//System.out.println(mail);//不可访问
//System.out.println(address);//不可访问
System.out.println(person.address);//可以访问内部类的事由成员
System.out.println(person.mail);//可以访问内部类的公有成员
}
public static void main(String[] args){
StaticTest st = new StaticTest();
st.printlnFo();
}
}
在静态嵌套内部类,不能访问外部类的非静态成员,这是由Java语法中“静态方法不能直接访问非静态成员”所限定,若想访问外部类的变量,必须通过其他方法解决,由于这个原因,静态嵌套类使用很少。如果外部类访问内部类的成员,可以通过内部类实例来访问。
二 : 在外部类中定义内部类
class Outer{
int outer_a = 10;
private class InnerOne{
//私有的内部类
public int inner_b = 20;
private int inner_c = 30;
int inner_d = 40;
public void display(){
System.out.println("display outer_a" + outer_a);
}
private void display2(){
System.out.println("display outer_a" + outer_a);
}
}
public InnerOne getInnerOne(){
//即使是对外公开的方法,外部类也无法调用
return new InnerOne();
}
class InnerTwo{
InnerOne innerx = getInnerOne(); //可以访问
public void show(){
//System.out.println(inner_b); //不可以访问Inner的成员
//System.out.println(inner.inner_b); //不可以直接访问Inner的任何成员和方法
innerx.display();//可以访问
innerx.display2();//可以访问
System.out.println(innerx.inner_b); //可以访问
System.out.println(innerx.inner_c); //可以访问
System.out.println(innerx.inner_d); //可以访问
}
}
void test(){
InnerOne inner = new InnerOne(); //可以访问
inner.display();
inner.display2();
//System.out.println("inner b" + inner_b); //不能访问内部类变量
System.out.println("inner b" + inner.inner_b); //可以访问
System.out.println("inner c" + inner.inner_c); //可以访问
System.out.println("inner d" + inner.inner_d); //可以访问
InnerTwo innerTwo = new InnerTwo();
innerTwo .show();
}
}
public class Test(){
public static void main(String args[]){
Outer outer = new Outer();
//Outer.Inner a = outer.getInnerOne();
//Inner类是私有的,外部类不能访问,如果Inner类是public,则可以outer.test();
}
}
三 : 在方法中定义内部类
public class FunOuter{
int out_a = 10;
public void test(){
class Inner{
String inner_a = "20";
void display(){
System.out.println(out_a );
}
}
Inner inner = new Inner();
inner.display();
}
public void showStr(String str){
//public String str1 = "hello world"; //不可定义,只允许final修饰
//static String str2 = "China"; //不可定义,只允许final修饰
String str3 = "test";
final String str4 = "final Str4";
class InnerTwo{
public void testPrint(){
System.out.println(out_a ); //可以直接访问外部类变量
//System.out.println(str); //不可以访问本方法内部的非final变量
//System.out.println(str3); //不可访问本方法内部的非final变量
System.out.println(str4); //只可访问本方法的final变量成员
}
}
InnerTwo innerTwo = new InnerTwo();
innerTwo.testPrint();
}
public void use(){
//Inner innerObj = new Inner(); //此时Inner已不可见了
//System.out.println(Inner.a); //此时Inner已不可见了
}
public static void main(String[] args){
FunOuter outer = new FunOuter();
outer.test();
}
}
上面的例子定义在方法内部的内部类的可见性更小, 它只在方法内部可见, 在外部类(及外部类的其它方法中)中都不可见了。同时, 它有一个特点, 就是方法内的内部类连本方法的成员变量都不可访问, 它只能访问本方法的final型成员。同时另一个需引起注意的是方法内部定义成员, 只允许final修饰或不加修饰符, 其它像static等均不可用。
四 :匿名内部类
public class AnonymousInnerClassDemo Applet{
public void init(){
addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent me){
showStatus("Mouse Pressed");
}
});
}
public void showStatus(String str){
System.out.println(str);
}
}
方法 addMouseListener 接受一个对象型的参数表达式,于是在参数里,定义了一个匿名内部类,这个类是一个 MouseAdapter 类型的类,同时在这个类中定义了一个继承的方法 mousePressed,整个类作为一个参数,这个类没有名称,但是当执行这个表达式时它被自动实例化,因为这个匿名内部类是定义在 AnonymousInnerClassDemo 类内部的,所以它可以访问它的方法 showStatus 。