<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    keep moving!

    We must not cease from exploration. And the end of all our exploring will be to arrive where we began and to know the place for the first time.
    隨筆 - 37, 文章 - 2, 評論 - 3, 引用 - 0
    數(shù)據(jù)加載中……

    Java中內(nèi)部匿名類的使用

    1.內(nèi)部類的定義和使用:  

    內(nèi)部類是在一個類的內(nèi)部嵌套定義的類,它可以是其它類的成員,也可以在一個語句塊的內(nèi)部定義,還可以在表達(dá)式內(nèi)部匿名定義。

      內(nèi)部類有如下特性:

      ◇ 一般用在定義它的類或語句塊之內(nèi),在外部引用它時必須給出完整的名稱.名字不能與包含它的類名相同。
      ◇ 可以使用包含它的類的靜態(tài)和實(shí)例成員變量,也可以使用它所在方法的局部變量。
      ◇ 可以定義為abstract。
      ◇ 可以聲明為private或protected。
      ◇ 若被聲明為static,就變成了頂層類,不能再使用局部變量。
      ◇ 若想在Inner Class中聲明任何static成員,則該Inner Class必須聲明為static。

      例3-8 是一個說明內(nèi)部類如何使用的例子,其中,定義了兩個內(nèi)部類:MouseMotionHandler和MouseEventHandler,分別用來處理鼠標(biāo)移動事件和鼠標(biāo)點(diǎn)按事件。

    【例3-8】
      import java.awt.*;
      import java.awt.event.*;
      public class TwoListenInner {
        private Frame f;
        private TextField tf;
          public static void main(String args[]) {
           TwoListenInner that=new TwoListenInner();
           that.go();
        }

          public void go() {
           f=new Frame("Two listeners example");
           f.add("North",new Label("Click and drag the mouse"));
           tf=new TextField(30);
           f.add("South",tf);
           f.addMouseMotionListener(new MouseMotionHandler());
           f.addMouseListener(new MouseEventHandler());
           f.setSize(300,300);
           f.setVisible(true);
        }
        public class MouseMotionHandler extends MouseMotionAdapter {
          public void mouseDragged(MouseEvent e){
           String s="Mouse dragging:X="+e.getX()+"Y="+e.getY();
           tf.setText(s);
          }
        }
        public class MouseEventHandler extends MouseAdapter {
          public void mouseEntered(MouseEvent e){
           String s="The mouse entered";
           tf.setText(s);
          }
          public void mouseExited(MouseEvent e){
           String s="The mouse left the building";
           tf.setText(s);
          }
        }
      }

      同學(xué)們可以運(yùn)行一下這個程序,看一看它的運(yùn)行結(jié)果。當(dāng)你將鼠標(biāo)移入frame時,文本框中會出現(xiàn):"The mouse entered";當(dāng)你在frame中拖曳鼠標(biāo)時,文本框中會出現(xiàn):"Mouse dragging:X= Y=117";當(dāng)鼠標(biāo)離開文本框時,文本框中出現(xiàn):"The mouse left the building"。

     2. 匿名類的定義和使用:

      匿名類是一種特殊的內(nèi)部類,它是在一個表達(dá)式內(nèi)部包含一個完整的類定義。通過對例6-7中g(shù)o()部分語句的修改,我們可以看到匿名類的使用情況。

      public void go() {
             f=new Frame("Two listeners example");
             f.add("North",new Label("Click and drag the mouse"));
             tf=new TextField(30);
             f.add("South",tf);
             f.addMouseMotionListener(new MouseMotionHandler(){
             /*定義了一個匿名類,類名沒有顯式地給出,只是該類是
              MouseMotionHandler類的子類*/
               public void mouseDragged(MouseEvent e){
                 String s="Mouse dragging:X="+e.getX()+"Y
                 ="+e.getY();
                 tf.setText(s);
               }
             });
             f.addMouseListener(new MouseEventHandler());

             f.setSize(300,300);
             f.setVisible(true);
             }

     3. 內(nèi)部類的優(yōu)缺點(diǎn):

      ◇ 優(yōu)點(diǎn):節(jié)省編譯后產(chǎn)生的字節(jié)碼文件的大小
      ◇ 缺點(diǎn):使程序結(jié)構(gòu)不清楚



     內(nèi)部類:一個內(nèi)部類的定義是定義在另一個內(nèi)部的類。

      原因是:

      1.一個內(nèi)部類的對象能夠訪問創(chuàng)建它的對象的實(shí)現(xiàn),包括私有數(shù)據(jù)。

      2.對于同一個包中的其他類來說,內(nèi)部類能夠隱藏起來。

      3.匿名內(nèi)部類可以很方便的定義回調(diào)。

      4.使用內(nèi)部類可以非常方便的編寫事件驅(qū)動程序。

      提起Java內(nèi)部類(Inner Class)可能很多人不太熟悉,實(shí)際上類似的概念在C++里也有,那就是嵌套類(Nested Class),關(guān)于這兩者的區(qū)別與聯(lián)系,在下文中會有對比。內(nèi)部類從表面上看,就是在類中又定義了一個類(下文會看到,內(nèi)部類可以在很多地方定義),而實(shí)際上并沒有那么簡單,乍看上去內(nèi)部類似乎有些多余,它的用處對于初學(xué)者來說可能并不是那么顯著,但是隨著對它的深入了解,你會發(fā)現(xiàn)Java的設(shè)計(jì)者在內(nèi)部類身上的確是用心良苦。學(xué)會使用內(nèi)部類,是掌握J(rèn)ava高級編程的一部分,它可以讓你更優(yōu)雅地設(shè)計(jì)你的程序結(jié)構(gòu)。下面從以下幾個方面來介紹:

      * 第一次見面

      public interface Contents {

      int value();

      }

      public interface Destination {

      String readLabel();

      }

      public class Goods {

      private class Content implements Contents {

      private int i = 11;

      public int value() {

      return i;

      }

      }

      protected class GDestination implements Destination {

      private String label;

      private GDestination(String whereTo) {

      label = whereTo;

      }

      public String readLabel() {

      return label;

      }

      }

      public Destination dest(String s) {

      return new GDestination(s);

      }

      public Contents cont() {

      return new Content();

      }

      }

      class TestGoods {

      public static void main(String[] args) {

      Goods p = new Goods();

      Contents c = p.cont();

      Destination d = p.dest("Beijing");

      }

      }

      在這個例子里類Content和GDestination被定義在了類Goods內(nèi)部,并且分別有著protected和private修飾符來控制訪問級別。Content代表著Goods的內(nèi)容,而GDestination代表著Goods的目的地。它們分別實(shí)現(xiàn)了兩個接口Content和 Destination。在后面的main方法里,直接用 Contents c和Destination d進(jìn)行操作,你甚至連這兩個內(nèi)部類的名字都沒有看見!這樣,內(nèi)部類的第一個好處就體現(xiàn)出來了??隱藏你不想讓別人知道的操作,也即封裝性。

      同時,我們也發(fā)現(xiàn)了在外部類作用范圍之外得到內(nèi)部類對象的第一個方法,那就是利用其外部類的方法創(chuàng)建并返回。上例中的cont()和dest()方法就是這么做的。那么還有沒有別的方法呢?當(dāng)然有,其語法格式如下:

      outerObject=new outerClass(Constructor Parameters);

      outerClass.innerClass innerObject=outerObject.new InnerClass(Constructor Parameters);

      注意在創(chuàng)建非靜態(tài)內(nèi)部類對象時,一定要先創(chuàng)建起相應(yīng)的外部類對象。至于原因,也就引出了我們下一個話題??

      * 非靜態(tài)內(nèi)部類對象有著指向其外部類對象的引用

      對剛才的例子稍作修改:

      public class Goods {

      private valueRate=2;

      private class Content implements Contents {

      private int i = 11*valueRate;

      public int value() {

      return i;

      }

      }

      protected class GDestination implements Destination {

      private String label;

      private GDestination(String whereTo) {

      label = whereTo;

      }

      public String readLabel() {

      return label;

      }

      }

      public Destination dest(String s) {

      return new GDestination(s);

      }

      public Contents cont() {

      return new Content();

      }

      }

      修改的部分用藍(lán)色顯示了。在這里我們給Goods類增加了一個private成員變量valueRate,意義是貨物的價值系數(shù),在內(nèi)部類Content的方法value()計(jì)算價值時把它乘上。我們發(fā)現(xiàn),value()可以訪問valueRate,這也是內(nèi)部類的第二個好處??一個內(nèi)部類對象可以訪問創(chuàng)建它的外部類對象的內(nèi)容,甚至包括私有變量!這是一個非常有用的特性,為我們在設(shè)計(jì)時提供了更多的思路和捷徑。要想實(shí)現(xiàn)這個功能,內(nèi)部類對象就必須有指向外部類對象的引用。 Java編譯器在創(chuàng)建內(nèi)部類對象時,隱式的把其外部類對象的引用也傳了進(jìn)去并一直保存著。這樣就使得內(nèi)部類對象始終可以訪問其外部類對象,同時這也是為什么在外部類作用范圍之外向要創(chuàng)建內(nèi)部類對象必須先創(chuàng)建其外部類對象的原因。
    [摘要] 提起Java內(nèi)部類(Inner Class)可能很多人不太熟悉,實(shí)際上類似的概念在C++里也有,那就是嵌套類(Nested Class),關(guān)于這兩者的區(qū)別與聯(lián)系,在下文中會有對比。
    [關(guān)鍵字] Java 內(nèi)部類 匿名類
      有人會問,如果內(nèi)部類里的一個成員變量與外部類的一個成員變量同名,也即外部類的同名成員變量被屏蔽了,怎么辦?沒事,Java里用如下格式表達(dá)外部類的引用:

      outerClass.this

      有了它,我們就不怕這種屏蔽的情況了。

      * 靜態(tài)內(nèi)部類

      和普通的類一樣,內(nèi)部類也可以有靜態(tài)的。不過和非靜態(tài)內(nèi)部類相比,區(qū)別就在于靜態(tài)內(nèi)部類沒有了指向外部的引用。這實(shí)際上和C++中的嵌套類很相像了,Java內(nèi)部類與C++嵌套類最大的不同就在于是否有指向外部的引用這一點(diǎn)上,當(dāng)然從設(shè)計(jì)的角度以及以它一些細(xì)節(jié)來講還有區(qū)別。

      除此之外,在任何非靜態(tài)內(nèi)部類中,都不能有靜態(tài)數(shù)據(jù),靜態(tài)方法或者又一個靜態(tài)內(nèi)部類(內(nèi)部類的嵌套可以不止一層)。不過靜態(tài)內(nèi)部類中卻可以擁有這一切。這也算是兩者的第二個區(qū)別吧。

      * 局部內(nèi)部類

      是的,Java內(nèi)部類也可以是局部的,它可以定義在一個方法甚至一個代碼塊之內(nèi)。

      public class Goods1 {

      public Destination dest(String s) {

      class GDestination implements Destination {

      private String label;

      private GDestination(String whereTo) {

      label = whereTo;

      }

      public String readLabel() { return label; }

      }

      return new GDestination(s);

      }

      public static void main(String[] args) {

      Goods1 g= new Goods1();

      Destination d = g.dest("Beijing");

      }

      }

      上面就是這樣一個例子。在方法dest中我們定義了一個內(nèi)部類,最后由這個方法返回這個內(nèi)部類的對象。如果我們在用一個內(nèi)部類的時候僅需要創(chuàng)建它的一個對象并創(chuàng)給外部,就可以這樣做。當(dāng)然,定義在方法中的內(nèi)部類可以使設(shè)計(jì)多樣化,用途絕不僅僅在這一點(diǎn)。

      下面有一個更怪的例子:

      public class Goods2{

      private void internalTracking(boolean b) {

      if(b) {

      class TrackingSlip {

      private String id;

      TrackingSlip(String s) {

      id = s;

      }

      String getSlip() { return id; }

      }

      TrackingSlip ts = new TrackingSlip("slip");

      String s = ts.getSlip();

      }

      }

      public void track() { internalTracking(true); }

      public static void main(String[] args) {

      Goods2 g= new Goods2();

      g.track();

      }

      }

      你不能在if之外創(chuàng)建這個內(nèi)部類的對象,因?yàn)檫@已經(jīng)超出了它的作用域。不過在編譯的時候,內(nèi)部類TrackingSlip和其他類一樣同時被編譯,只不過它由它自己的作用域,超出了這個范圍就無效,除此之外它和其他內(nèi)部類并沒有區(qū)別。

      * 匿名內(nèi)部類

      java的匿名內(nèi)部類的語法規(guī)則看上去有些古怪,不過如同匿名數(shù)組一樣,當(dāng)你只需要創(chuàng)建一個類的對象而且用不上它的名字時,使用內(nèi)部類可以使代碼看上去簡潔清楚。它的語法規(guī)則是這樣的:

      new interfacename(){......}; 或 new superclassname(){......};

      下面接著前面繼續(xù)舉例子:

      public class Goods3 {

      public Contents cont(){

      return new Contents(){

      private int i = 11;

      public int value() {

      return i;

      }

      };

      }

      }

      這里方法cont()使用匿名內(nèi)部類直接返回了一個實(shí)現(xiàn)了接口Contents的類的對象,看上去的確十分簡潔。

      在java的事件處理的匿名適配器中,匿名內(nèi)部類被大量的使用。例如在想關(guān)閉窗口時加上這樣一句代碼:

      frame.addWindowListener(new WindowAdapter(){

      public void windowClosing(WindowEvent e){

      System.exit(0);

      }

      });

      有一點(diǎn)需要注意的是,匿名內(nèi)部類由于沒有名字,所以它沒有構(gòu)造函數(shù)(但是如果這個匿名內(nèi)部類繼承了一個只含有帶參數(shù)構(gòu)造函數(shù)的父類,創(chuàng)建它的時候必須帶上這些參數(shù),并在實(shí)現(xiàn)的過程中使用super關(guān)鍵字調(diào)用相應(yīng)的內(nèi)容)。如果你想要初始化它的成員變量,有下面幾種方法:

      1. 如果是在一個方法的匿名內(nèi)部類,可以利用這個方法傳進(jìn)你想要的參數(shù),不過記住,這些參數(shù)必須被聲明為final。

      2. 將匿名內(nèi)部類改造成有名字的局部內(nèi)部類,這樣它就可以擁有構(gòu)造函數(shù)了。

      3. 在這個匿名內(nèi)部類中使用初始化代碼塊。

      * 為什么需要內(nèi)部類?

      java內(nèi)部類有什么好處?為什么需要內(nèi)部類?

      首先舉一個簡單的例子,如果你想實(shí)現(xiàn)一個接口,但是這個接口中的一個方法和你構(gòu)想的這個類中的一個方法的名稱,參數(shù)相同,你應(yīng)該怎么辦?這時候,你可以建一個內(nèi)部類實(shí)現(xiàn)這個接口。由于內(nèi)部類對外部類的所有內(nèi)容都是可訪問的,所以這樣做可以完成所有你直接實(shí)現(xiàn)這個接口的功能。

      不過你可能要質(zhì)疑,更改一下方法的不就行了嗎?

      的確,以此作為設(shè)計(jì)內(nèi)部類的理由,實(shí)在沒有說服力。

      真正的原因是這樣的,java中的內(nèi)部類和接口加在一起,可以的解決常被C++程序員抱怨java中存在的一個問題??沒有多繼承。實(shí)際上,C++的多繼承設(shè)計(jì)起來很復(fù)雜,而java通過內(nèi)部類加上接口,可以很好的實(shí)現(xiàn)多繼承的效果。

      本文的目的只是向大家介紹一下內(nèi)部類的概念以及使用方法,在后續(xù)文章里,將會針對本文中的內(nèi)容舉更多具體的例子,以及介紹如何使用內(nèi)部類構(gòu)建一個Applicaton Framework

    posted on 2008-09-07 11:46 大石頭 閱讀(1047) 評論(0)  編輯  收藏 所屬分類: 基礎(chǔ)

    主站蜘蛛池模板: 亚洲午夜福利在线视频| 亚洲人成电影福利在线播放| 亚洲乱码一二三四区乱码| 99免费在线观看视频| 久久精品国产亚洲AV无码偷窥| 中文字幕无码日韩专区免费| 亚洲伦理一二三四| 一级毛片成人免费看免费不卡| 精品无码国产污污污免费| 亚洲人成小说网站色| 成人在线免费观看| 亚洲免费精彩视频在线观看| 久久精品国产免费| 亚洲黄色中文字幕| 久久99精品免费一区二区| 中国亚洲女人69内射少妇| 你懂得的在线观看免费视频| 久久亚洲精品中文字幕无码| 最近免费中文字幕大全免费| 亚洲国产成AV人天堂无码| 全免费一级毛片在线播放| 美女视频黄a视频全免费网站色| 免费黄色网址网站| 国产精品亚洲综合五月天| 国产乱子伦精品免费无码专区| 老司机午夜性生免费福利| 国外亚洲成AV人片在线观看| 99久久综合精品免费| 亚洲妇女熟BBW| 亚洲国产av无码精品| 久久精品国产这里是免费| 亚洲一区二区久久| 免费v片在线观看| 亚洲av成人中文无码专区| 又粗又大又黑又长的免费视频 | 59pao成国产成视频永久免费| 亚洲av永久无码嘿嘿嘿| 国产美女做a免费视频软件| 你懂的在线免费观看| 亚洲国产乱码最新视频| 亚洲综合色成在线播放|