Dict.CN 在線詞典, 英語(yǔ)學(xué)習(xí), 在線翻譯

          都市淘沙者

          荔枝FM Everyone can be host

          統(tǒng)計(jì)

          留言簿(23)

          積分與排名

          優(yōu)秀學(xué)習(xí)網(wǎng)站

          友情連接

          閱讀排行榜

          評(píng)論排行榜

          深入理解嵌套類和內(nèi)部類

          一、什么是嵌套類及內(nèi)部類?
          ????可以在一個(gè)類的內(nèi)部定義另一個(gè)類,這種類稱為嵌套類(nested classes),它有兩種類型: 靜態(tài)嵌套類和非靜態(tài)嵌套類。靜態(tài)嵌套類使用很少,最重要的是非靜態(tài)嵌套類,也即是被稱作為內(nèi)部類(inner)。嵌套類從JDK1.1開始引入。其中inner類又可分為三種:
          ????其一、在一個(gè)類(外部類)中直接定義的內(nèi)部類;
          ????其二、在一個(gè)方法(外部類的方法)中定義的內(nèi)部類;
          ????其三、匿名內(nèi)部類。
          下面,我將說(shuō)明這幾種嵌套類的使用及注意事項(xiàng)。


           
          二、靜態(tài)嵌套類
          ????如下所示代碼為定義一個(gè)靜態(tài)嵌套類,

          public class StaticTest {
          ??private static String name = "javaJohn";
          ??private String id = "X001";

          ??static class Person{
          ????private String address = "swjtu,chenDu,China";
          ????public String mail = "josserchai@yahoo.com";//內(nèi)部類公有成員
          ????public void display(){
          ??????//System.out.println(id);//不能直接訪問(wèn)外部類的非靜態(tài)成員
          ??????System.out.println(name);//只能直接訪問(wèn)外部類的靜態(tài)成員
          ??????System.out.println("Inner "+address);//訪問(wèn)本內(nèi)部類成員。
          ????}
          ??}

          ???public void printInfo(){
          ?????Person person = new Person();
          ?????person.display();

          ?????//System.out.println(mail);//不可訪問(wèn)
          ?????//System.out.println(address);//不可訪問(wèn)

          ?????System.out.println(person.address);//可以訪問(wèn)內(nèi)部類的私有成員
          ?????System.out.println(person.mail);//可以訪問(wèn)內(nèi)部類的公有成員

          ???}

          ???public static void main(String[] args) {
          ???????StaticTest staticTest = new StaticTest();
          ???????staticTest.printInfo();
          ???}
          }

          ?????在靜態(tài)嵌套類內(nèi)部,不能訪問(wèn)外部類的非靜態(tài)成員,這是由Java語(yǔ)法中"靜態(tài)方法不能直接訪問(wèn)非靜態(tài)成員"所限定。
          若想訪問(wèn)外部類的變量,必須通過(guò)其它方法解決,由于這個(gè)原因,靜態(tài)嵌套類使用很少。注意,外部類訪問(wèn)內(nèi)
          部類的的成員有些特別,不能直接訪問(wèn),但可以通過(guò)內(nèi)部類實(shí)例來(lái)訪問(wèn),這是因?yàn)殪o態(tài)嵌套內(nèi)的所有成員和方法默認(rèn)為
          靜態(tài)的了。同時(shí)注意,內(nèi)部靜態(tài)類Person只在類StaticTest 范圍內(nèi)可見,若在其它類中引用或初始化,均是錯(cuò)誤的。

          三、在外部類中定義內(nèi)部類
          ????如下所示代碼為在外部類中定義兩個(gè)內(nèi)部類及它們的調(diào)用關(guān)系:

          class Outer{
            int outer_x = 100;
          
            private class Inner{//私有的內(nèi)部類
             public int y = 10;
             private int z = 9;
             int m = 5;
             public void display(){
               System.out.println("display outer_x:"+ outer_x);
             }
          
             private void display2(){
              System.out.println("display outer_x:"+ outer_x);
             }
          
          }
          
           public Inner getInner(){//即使是對(duì)外公開的方法,外部類也無(wú)法調(diào)用
             return new Inner();
           }
          
           void test(){ 
             Inner inner = new Inner(); //可以訪問(wèn)
             inner.display();
             inner.display2();
             //System.out.println("Inner y:" + y);//不能訪問(wèn)內(nèi)部?jī)?nèi)變量
             System.out.println("Inner y:" + inner.y);//可以訪問(wèn)
             System.out.println("Inner z:" + inner.z);//可以訪問(wèn)
             System.out.println("Inner m:" + inner.m);//可以訪問(wèn)
          
             InnerTwo innerTwo = new InnerTwo();
             innerTwo.show();
           }
          
           class InnerTwo{
             Inner innerx = getInner();//可以訪問(wèn)
             public void show(){
              //System.out.println(y);//不可訪問(wèn)Innter的y成員
              //System.out.println(Inner.y);//不可直接訪問(wèn)Inner的任何成員和方法
              innerx.display();//可以訪問(wèn)
              innerx.display2();//可以訪問(wèn)
              System.out.println(innerx.y);//可以訪問(wèn)
              System.out.println(innerx.z);//可以訪問(wèn)
              System.out.println(innerx.m);//可以訪問(wèn)
             }
           }
          
          }
          
          public class Test
          {
           public static void main(String args[]){
            
            Outer outer = new Outer();
           // Outer.Inner a=outer.getInner();//Inner類是私有的,外部類不能訪問(wèn),如果Inner類是public ,則可以。
            outer.test();
           }
          }

          ????內(nèi)部類Inner及InnterTwo只在類Outer的作用域內(nèi)是可知的,如果類Outer外的任何代碼嘗試初始化類Inner或使用它,編譯就不會(huì)通過(guò)。同時(shí),內(nèi)部類的變量成員只在內(nèi)部?jī)?nèi)內(nèi)部可見,若外部類或同層次的內(nèi)部類需要訪問(wèn),需采用示例程序
          中的方法,不可直接訪問(wèn)內(nèi)部類的變量。

          四、在方法中定義內(nèi)部類
          ????如下所示代碼為在方法內(nèi)部定義一個(gè)內(nèi)部類:

          public class FunOuter { 
           int out_x = 100;
          
           public void test(){
            class Inner{
              String x = "x";
              void display(){
                 System.out.println(out_x);
              }
            }
           Inner inner = new Inner();
           inner.display();
          }
          
          public void showStr(String str){
            //public String str1 = "test Inner";//不可定義,只允許final修飾
            //static String str4 = "static Str";//不可定義,只允許final修飾
            String str2 = "test Inner";
            final String str3 = "final Str";
            class InnerTwo{
              public void testPrint(){
              System.out.println(out_x);//可直接訪問(wèn)外部類的變量
              //System.out.println(str);//不可訪問(wèn)本方法內(nèi)部的非final變量
              //System.out.println(str2);//不可訪問(wèn)本方法內(nèi)部的非final變量
              System.out.println(str3);//只可訪問(wèn)本方法的final型變量成員
              }
            }
            InnerTwo innerTwo = new InnerTwo();
            innerTwo.testPrint();
          }
          
          public void use(){
             //Inner innerObj = new Inner();//此時(shí)Inner己不可見了。
             //System.out.println(Inner.x);//此時(shí)Inner己不可見了。
          }
          
          
           public static void main(String[] args) {
            FunOuter outer = new FunOuter();
            outer.test();
           }
          }
          
          


          ????從上面的例程我們可以看出定義在方法內(nèi)部的內(nèi)部類的可見性更小,它只在方法內(nèi)部 可見,在外部類(及外部類的其它方法中)中都不可見了。同時(shí),它有一個(gè)特點(diǎn),就是方法內(nèi)的內(nèi)部類連本方法的成員變量都不可訪問(wèn),它只能訪問(wèn)本方法的final型成員。同時(shí)另一個(gè)需引起注意的是方法內(nèi)部定義成員,只允許final修飾或不加修飾符,其它像static等均不可用。

          五、匿名內(nèi)部類
          ????如下所示代碼為定義一個(gè)匿名內(nèi)部類:匿名內(nèi)部類通常用在Java的事件處理上


          import java.applet.*;
          import java.awt.event.*;

          ????public class AnonymousInnerClassDemo extends 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接受一個(gè)對(duì)象型的參數(shù)表達(dá)式,于是,在參數(shù)里,我們定義了一個(gè)匿名內(nèi)部類,這個(gè)類是一個(gè)MouseAdapter類型的類,同時(shí)在這個(gè)類中定義了一個(gè)繼承的方法mousePressed,整個(gè)類做為一個(gè)參數(shù)。這個(gè)類沒(méi)有名稱,但是當(dāng)執(zhí)行這個(gè)表達(dá)式時(shí)它被自動(dòng)實(shí)例化。同時(shí)因?yàn)椋@個(gè)匿名內(nèi)部類是定義在AnonymousInnerClassDemo 類內(nèi)部的,所以它可以訪問(wèn)它的方法showStatus。這同前面的內(nèi)部類是一致的。

          六、內(nèi)部類使用的其它的問(wèn)題

          ?????通過(guò)以上,我們可以清楚地看出內(nèi)部類的一些使用方法,同時(shí),在許多時(shí)候,內(nèi)部類是在如Java的事件處理、或做為值對(duì)象來(lái)使用的。同時(shí),我們需注意最后一個(gè)問(wèn)題,那就是,內(nèi)部類同其它類一樣被定義,同樣它也可以繼承外部其它包的類和實(shí)現(xiàn)外部其它地方的接口。同樣它也可以繼承同一層次的其它的內(nèi)部類,甚至可以繼承外部類本身。下面我們給出最后一個(gè)例子做為結(jié)束:


          public class Layer {
            //Layer類的成員變量
            private String testStr = "testStr";
          
            //Person類,基類
            class Person{
              String name;
              Email email;
              public void setName(String nameStr){
               this.name = nameStr;
              }
          
              public String getName(){
                return this.name;
              } 
          
              public void setEmail(Email emailObj){
                this.email = emailObj;
              }
          
              public String getEmail(){
                return this.email.getMailStr();
              }
          
              //內(nèi)部類的內(nèi)部類,多層內(nèi)部類
              class Email{ 
               String mailID;
               String mailNetAddress;
          
               Email(String mailId,String mailNetAddress){
               this.mailID = mailId;
               this.mailNetAddress = mailNetAddress;
               }
          
               String getMailStr(){
                  return this.mailID +"@"+this.mailNetAddress;
               }
              } 
            }
          
             //另一個(gè)內(nèi)部類繼承外部類本身
             class ChildLayer extends Layer{
               void print(){
                 System.out.println(super.testStr);//訪問(wèn)父類的成員變量
               }
             }
          
             //另個(gè)內(nèi)部類繼承內(nèi)部類Person
              class OfficePerson extends Person{ 
               void show(){
                 System.out.println(name);
                 System.out.println(getEmail()); 
               }
              }
          
              //外部類的測(cè)試方法 
              public void testFunction(){
                //測(cè)試第一個(gè)內(nèi)部類
                ChildLayer childLayer = new ChildLayer();
                childLayer.print();
          
                //測(cè)試第二個(gè)內(nèi)部類
                OfficePerson officePerson = new OfficePerson();
                officePerson.setName("abner chai");
                //注意此處,必須用對(duì)象.new 出來(lái)對(duì)象的子類對(duì)象
                //而不是Person.new Email(...)
                //也不是new Person.Email(...)
                officePerson.setEmail(officePerson.new Email("josserchai","yahoo.com"));
          
                 officePerson.show();
              }
          
               public static void main(String[] args) {
                Layer layer = new Layer();
                layer.testFunction();
               }
          }
          

          posted on 2006-04-26 15:22 都市淘沙者 閱讀(170) 評(píng)論(0)  編輯  收藏 所屬分類: Java Basic/Lucene/開源資料

          主站蜘蛛池模板: 松江区| 长沙市| 河津市| 牟定县| 大关县| 昌都县| 余江县| 岗巴县| 平安县| 大洼县| 松滋市| 玉山县| 新泰市| 黄冈市| 武定县| 隆昌县| 海南省| 滁州市| 惠安县| 深泽县| 迭部县| 忻城县| 安达市| 板桥市| 墨竹工卡县| 石景山区| 泊头市| 申扎县| 肇源县| 陇西县| 义乌市| 永昌县| 阜城县| 安阳市| 精河县| 昌平区| 通河县| 进贤县| 岳阳县| 阳新县| 天门市|