关于JAVA匿名内部类的一点接头
副标题#e#根基理论:
关于JAVA内部类:一个内部类的界说是界说在另一个类内部的类。
存在它的原因是:
1.一个内部类的工具可以或许会见建设它的工具的实现,包罗私有数据。即内部类实例对包括它的哪个类的实例来说,是特权的。
2.对付同一个包中的其他类来说,内部类可以或许埋没起来,换句话说,内部类不管要领的可见性如何,那怕是public,除了海涵类,其他类都无法利用它。
3.匿名内部类可以很利便的界说回调。
4.利用内部类可以很是利便的编写事件驱动措施。
其实它真正的目标仅仅为了界说回调--进一步就是事件驱动。
接口和回调:编程一个常用的模式是回调模式,在这种模式中你可以指定当一个特按时间产生时回调工具上的要领。
留意事项:
匿名类和内部类中的中的this :
有时候,我们会用到一些内部类和匿名类。当在匿名类顶用this时,这个this则指的是匿名类或内部类自己。
这时假如我们要利用外部类的要领和变量的话,则应该加上外部类的类名。如下面这个例子:
public class A { int i = 1; public A() { Thread thread = new Thread() { public void run() { for(;;) { A.this.run(); try { sleep(1000); } catch(InterruptedException ie) { } } } }; thread.start(); } public void run() { System.out.println("i = " + i); i++; } public static void main(String[] args) throws Exception { new A(); } }
在上面这个例子中, thread 是一个匿名类工具,在它的界说中,它的 run 函数里用到了外部类的 run 函数。
这时由于函数同名,直接挪用就不可了。这时有两种步伐,一种就是把外部的 run 函数换一个名字,但这种步伐对付一个开拓到半途的应用来说是不行取的
。那么就可以用这个例子中的步伐用外部类的类名加上 this 引用来说明要挪用的是外部类的要领 run。
对付这个例子: this.test(new Inner(){ public void method1(){ System.out.print("1111"); } public void method2(){ System.out.print("22222"); } });
这个时候挪用test()要领,那Inner类的method1和method2是什么时候被挪用的?莫非也是this工具向他们动员静(好比传入一个参数)吗?照旧直接显式的挪用??
对付Inner类,除了this这个类,就是this.test(…那句中的this,它可以或许挪用Inner类的要领,其他处所都不可,然而,这也需要你在类中有个处所生存有对这个内部类实例的引用才可以。再说明一次,内部类是用来在某个时刻挪用外面的要领而存在的--这就是回调。
为了说明内部类实例的要领只能在海涵类的实例中挪用,其他处所无法挪用,给个例子如下:
JAVA2实用教程源码:
/** 一个应用措施,用来演示内部类的利用 */
/** 类Outer */
class Outer{
private static int size;
/** 内部类Inner的声明 */
public class Inner{
private int size;
/** 要领doStuff() */
public void doStuff(int size){
size++; //存取局部变量
this.size++; //存取其内部类的成员变量
Outer.this.size++; //存取其外部类的成员变量
System.out.println(size+" "+this.size+" "+Outer.this.size);
}
}//内部类Inner竣事
/** 类Outer中界说的实例要领testInner()要领 */
public void testInner(){
Inner i=new Inner();
i.doStuff(5);
}
/** main()要领 */
public static void main(String[] a){
Outer o=new Outer();
o.testInner();
}
}//类Outer竣事
#p#副标题#e#
那么,如何利用内部类,匿名类实现事件处理惩罚呢?
JAVA—事件适配器
1.事件适配器–EventAdapter
下例中回收了鼠标适配器:
import java.awt.*; import java.awt.event.*; public class MouseClickHandler extends MouseAdaper{ public void mouseClicked(MouseEvent e) //只实现需要的要领 { ……} } java.awt.event包中界说的事件适配器类包罗以下几个: 1.ComponentAdapter( 组件适配器) 2.ContainerAdapter( 容器适配器) 3.FocusAdapter( 核心适配器) 4.KeyAdapter( 键盘适配器) 5.MouseAdapter( 鼠标适配器) 6.MouseMotionAdapter( 鼠标举动适配器) 7.WindowAdapter( 窗口适配器)
2. 用内部类实现事件处理惩罚
内部类(inner class)是被界说于另一个类中的类,利用内部类的主要原因是由于:
◇ 一个内部类的工具可会见外部类的成员要领和变量,包罗私有的成员。
◇ 实现事件监听器时,回收内部类、匿名类编程很是容易实现其成果。
◇ 编写事件驱动措施,内部类很利便。
因此内部类所可以或许应用的处所往往是在AWT的事件处理惩罚机制中。
例5.11
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(); } }//内部类竣事 }
#p#分页标题#e#
3.匿名类(Anonymous Class)
当一个内部类的类声名只是在建设此类工具时用了一次,并且要发生的新类需担任于一个已有的父类或实现一个接口,才气思量用匿名类,由于匿名类自己无名,因此它也就不存在结构要领,它需要显示地挪用一个无参的父
类的结构要领,而且重写父类的要领。所谓的匿名就是该类连名字都没有,只是显示地挪用一个无参的父类的结构要领。
例5.12
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(); } }
其实仔细阐明,例5.11和5.12实现的都是完全一样的成果,只不外采纳的方法差异。5.11中的事件处理惩罚类是一个内部类,而5.12的事件处理惩罚类是匿名类,可以说从类的干系来说是越来越不清楚,但
是措施也越来越简洁。熟悉这两种方法也十分有助于编写图形界面的措施。
亲自在IDE中实践一下,会领略的更深切一点。