关于java内部类的说明,简单的定义就是定义在另一个类内部的类。
原因是:
1.内部类可以访问外部类方法变量,包括私有数据。
2.对于同一个包里面的其他类,内部类可以很好的隐藏起来。
3.匿名内部类可以很方便的实现回调。
4.使用内部类可以很方便的编写事件驱动程序。
注意:定义在类中方法之外的内部类分为实例内部类和静态内部类,实例内部类自动持有外部类的引用,可以访问外部类所有变量,但是静态内部类只能访问外部类的静态成员,定义在方法内的外部类叫局部内部类,该类如果访问方法内的变量和参数一定要被final修饰,它也可以无条件访问外部变量。
匿名内部类既然叫匿名,那么名字对于该类已经不是多重要,因为该匿名类的实例本来就不打算给别的类使用或者重复使用,仅限于类内部使用或者使用一次,所以就不需要类名了,没有类名匿名内部类也就没有构造方法。
为什么内部类可以访问外部类所有变量,因为Java 编译器在创建内部类对象时,隐式的把其外部类对象的引用也传了进去并一直保存着。这样就使得内部类对象始终可以访问其外部类对象,同时这也是为什么在外部类作用范围之外向要创建内部类对象必须先创建其外部类对象的原因。
如果外部类和内部类的成员变量同名,怎么办?内部类的成员变量就用this来引用,如果要用外部类的成员变量就用(外部类名.this)这个格式表述外部类的引用。
在java的事件处理的匿名适配器中,匿名内部类被大量使用。
网上说明内部类和匿名类的例子特别多,我也就随便摘抄几个,也为了让大家都明白什么样的形式叫内部类和匿名类。
内部类代码:
[java] view plain copy print
1. import
2. import
3. public class
4. private
5. private
6. public
7. new Frame("Inner classes example");
8. new TextField(30);
9. }
10.
11. public
12. new Label("Click and drag the mouse");
13. f.add(label,BorderLayout.NORTH);
14. f.add(tf,BorderLayout.SOUTH);
15. new MyMouseMotionListener());/*参数为内部类对象*/
16. 300,200);
17. true);
18. }
19.
20. class MyMouseMotionListener extends MouseMotionAdapter{ /*内部类开始*/
21. public void
22. "Mouse dragging: x="+e.getX()+"Y="+e.getY();
23. tf.setText(s); }
24. } ;
25.
26. public static void
27. new
28. obj.launchFrame();
29. }
30. //内部类结束
31. }
import java.awt.* ;
import java.awt.event.*;
public class InnerClass{
private Frame f;
private TextField tf;
public InnerClass(){
f=new Frame("Inner classes example");
tf=new TextField(30);
}
public voidi launchFrame(){
Label label=new Label("Click and drag the mouse");
f.add(label,BorderLayout.NORTH);
f.add(tf,BorderLayout.SOUTH);
f.addMouseMotionListener(new MyMouseMotionListener());/*参数为内部类对象*/
f.setSize(300,200);
f.setVisible(true);
}
class MyMouseMotionListener extends MouseMotionAdapter{ /*内部类开始*/
public void mouseDragged(MouseEvent e) {
String s="Mouse dragging: x="+e.getX()+"Y="+e.getY();
tf.setText(s); }
} ;
public static void main(String args[]) {
InnerClass obj=new InnerClass();
obj.launchFrame();
}
}//内部类结束
}
从上面的代码可以看出来,我在InnerClass定义了一个内部类MyMouseMotionListener继承了MouseMotionAdapter。然后在上面的方法调用中把子类对象传进去就行。这是一个简单的内部类实现一个事件监听器。如果是匿名类实现事件监听器,就不需要固定的子类去实现接口或者继承抽象类,直接在上面的方法调用中直接new抽象类或者接口对象。代码:
[java] view plain copy print
1. import
2. import
3. public class
4. private
5. private
6. public
7. new Frame("Inner classes example");
8. new TextField(30);
9. }
10. public void
11. new Label("Click and drag the mouse");
12. f.add(label,BorderLayout.NORTH);
13. f.add(tf,BorderLayout.SOUTH);
14. new MouseMotionAdapter(){ //匿名类开始
15. public void
16. "Mouse dragging: x="+e.getX()+"Y="+e.getY();
17. tf.setText(s); }
18. //匿名类结束
19. 300,200);
20. true);
21. }
22. public static void
23. new
24. obj.launchFrame();
25. }
26. }
import java.awt.* ;
import java.awt.event.*;
public class AnonymousClass{
private Frame f;
private TextField tf;
public AnonymousClass(){
f=new Frame("Inner classes example");
tf=new TextField(30);
}
public void launchFrame(){
Label label=new Label("Click and drag the mouse");
f.add(label,BorderLayout.NORTH);
f.add(tf,BorderLayout.SOUTH);
f.addMouseMotionListener(new MouseMotionAdapter(){ //匿名类开始
public void mouseDragged(MouseEvent e){
String s="Mouse dragging: x="+e.getX()+"Y="+e.getY();
tf.setText(s); }
} ); //匿名类结束
f.setSize(300,200);
f.setVisible(true);
}
public static void main(String args[]) {
AnonymousClass obj=new AnonymousClass();
obj.launchFrame();
}
}
可以看出来这两段代码实现的功能一样,只是采取的方式不同而已,再强调一遍如果是定义在方法里面的匿名内部类,如果想通过方法传入你想要的参数,这些参数必须被声明为final类型,如果要调用方法内部的变量,也必须声明为final类型。一般IDE工具都会提示,不然会报错的。