關於JAVA匿名內部類,回調,事件模式的一點討論


關於JAVA匿名內部類的一點討論.
基本理論:
-----------------------------------------------------
關於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結束

 

------------------------------------------------
那么,如何使用內部類,匿名類實現事件處理呢?

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();
       }
     }
// 內部類結束
    }


 

 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中實踐一下,會理解的更深切一點。

轉自:http://www.cnblogs.com/sgsoft/archive/2004/09/11/42148.html
 

再分享一下我老師大神的人工智能教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智能的隊伍中來!https://blog.csdn.net/jiangjunshow


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM