乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      類、抽象類、接口、繼承和對象(java)

       執(zhí)著男孩 2006-09-13

       


      這不是什么教材,筆者有時會在論壇上瞧瞧,看到不少初學(xué)者問到很多問題,這些問題是java程序員應(yīng)該懂得的,而一般書上不會講到或者一筆帶過的知識。因此斗膽涂鴉一篇文章,把想說的在這里一口氣說完。這也是本人第一次寫技術(shù)性的文章,文筆不暢之外,還請各位見諒。


      首先講清楚類和對象的區(qū)別。


      類是廣泛的概念,表示一個有共同性質(zhì)的群體,而對象指的是具體的一個實(shí)實(shí)在在的東西。例如,“人”是一個類,它可以表示地球上所有的人;而“張三”、“李四”、“愛因斯坦”等則是一個個的對象,或者說它們是“人”這個類的一個個實(shí)例。在 Java 中,我們可以定義類,然后創(chuàng)建類的對象。


      例如:
      // 聲明一個類“Human”
      class Human{
          private String name;
          public String getName(){
              return name;
          }
          public void setName(String value){
              this.name = value;
          }
          //......
      }


      創(chuàng)建一個類:
      Human human = new Human();


       


      其次,很多人對對象和對象的引用認(rèn)識模糊
      引用是程序操作對象的句柄,相當(dāng)于C和C++中的指針。
      前面說了,對象是一個實(shí)實(shí)在在的東西,比如前面的代碼:
      Human human = new Human();
      程序執(zhí)行到這里之后,java虛擬機(jī)將會在內(nèi)存中創(chuàng)建一個 Human 對象,并將這個對象的引用賦給 human 變量。這里有兩步,首先是創(chuàng)建 Human 對象,然后把創(chuàng)建的對象的引用賦給 human 變量。
      如果聲明了一個對象的引用,但沒有將對象賦值給它,則這個引用指向了空的對象,或者說引用了不存在的對象。這時如果想通過這個引用訪問對象,則會拋出空指針異常,例如:
      Human human;
      //......
      human.setName("張三");


       


      下面重點(diǎn)談一談類、抽象類、接口和繼承之間的關(guān)系
      不少細(xì)心的初學(xué)者在論壇上問類似這樣的問題:
      1、接口不實(shí)現(xiàn)方法,但我卻在程序中可以調(diào)用接口的方法,這是為什么?比如 java.sql 包中的 Connection、Statement、ResultSet 等都是接口,怎么可以調(diào)用 它們的方法呢?
      2、抽象類不能實(shí)例化,但是jdk中卻有很多抽象類的對象,這是為什么?比如 System.in 是一個 InputStream 類型對象,但 InputStream 是抽象類,怎么可以得到它的對象呢?


      不管怎么樣,大家應(yīng)該明白一點(diǎn):不管是抽象類中的抽象方法,還是接口中定義的方法,都是需要被調(diào)用的,否則這些方法定義出來就沒有意義了。


      可能有很多書上沒有提到,或者提到了而讀者沒有注意到這一點(diǎn):
      一個子類如果繼承了它的基類,則表示這個類也是其基類的一種類型,這個子類的一個對象是子類類型,并且同時也是其基類的一個對象,它也具有基其類的類型;一個類如果實(shí)現(xiàn)了一個接口,則表示這個類的一個對象也是這個接口的一個對象。


      可能這樣說不太好懂,又是子類、基類、類型、接口什么的,容易搞混。其實(shí)舉個現(xiàn)實(shí)的例子你就會覺得其實(shí)很簡單:
      如果“人”是一個基類,則“男人”是“人”的一個子類。如果“張三”是一個“男人”,也就是說“張三”是“男人”的一個對象,那么顯然“張三”也是“人”這個基類的一個對象。


      明白了這一點(diǎn),就容易理解為什么我們可以得到抽象類的對象了:原來我們得到的抽象類的對象其實(shí)是它的已經(jīng)實(shí)現(xiàn)了抽象方法的子類或子孫類的一個對象,但我們拿它當(dāng)它的抽象類的基類來用。比如“人”這個類,每個人都會“悲傷”,男人悲傷的時候抽煙、喝酒,女人悲傷的時候哭泣、流淚。由于不同的子類在“悲傷”時所進(jìn)行的動作不一樣,因此這個動作(方法)在基類中不好實(shí)現(xiàn),但基類中又需要有這個方法,因此,“人”這個類就可以定義一個抽象方法“悲傷”,由其子類“男人”和“女人”來實(shí)現(xiàn)“悲傷”這個方法。但是調(diào)用者只把男人和女人的對象當(dāng)作其基類“人”的一個對象,調(diào)用它的“悲傷”方法。
      讀者可以去體驗(yàn)一下 jdk 的抽象類 java.lang.Process :
      Runtime runtime = Rumtime.getRuntime();
      Process process = rumtime.exec("notepad.exe");
      Class cls = process.getClass();
      System.out.println(cls.getName());
      這時會打印出 process 類的名字,如果在 Windows 下它會是一個類似于 *Win32* 的名字,它是 Process 的一個子類。因?yàn)?process 類用于管理打開的進(jìn)程,而在不同的操作系統(tǒng)上都有不同的實(shí)現(xiàn),因此它把方法定義為 Process 的抽象方法,而具體的操作只能由對應(yīng)在不同操作系統(tǒng)下的子實(shí)現(xiàn)。



      下面來談接口,我們知道接口只定義了一些方法,而沒有實(shí)現(xiàn)這些方法。而其實(shí),接口是一個規(guī)范,它規(guī)定了實(shí)現(xiàn)這個接口所要做的事情,或者說規(guī)定了實(shí)現(xiàn)接口的類必須具備的能力(也就是方法)。
      那么我們可以這樣對比:
      某種類型的駕駛執(zhí)照,規(guī)定了拿到這個駕照的人必須能夠“開小汽車”和“開公共汽車”。那么我們認(rèn)為這個駕照是一個接口,它規(guī)定了實(shí)現(xiàn)它的類所必須有的能力。
      我們可以定義一個類 Driver,繼承自 Human,然后實(shí)現(xiàn)“駕照持有者”這個接口:
      public interface DriverHolder{
          public void driverCar();
          public void driverBus();
      }
      public class Driver extends Human implements DriverHolder{
          public void driverCar(){
              // ......
          }
          public void driverBus(){
              // ......
          }
      }



      這樣一來,一個“Driver”對象,它同時也是一個 DrivreHolder 對象。即一個司機(jī)(Driver)同時是一個駕照執(zhí)持有者對象。在程序中我們可以這樣:
      DriverHolder driverholder = new Driver();
      driverholder.driverCar();


      這樣我們就解釋了為什么“接口沒有實(shí)現(xiàn)方法,卻可以得到接口類的對象”的問題。


      但是這樣一來,肯定有人會問:為什么要定義一個接口呢,為什么不直接把這個方法定義到 Driver 類中去,然后 Driver driver = new Driver(); 一樣可以調(diào)用它的 driverCar(); 和 driverBus() 方法,這樣做豈不是方便得多?


      這是因?yàn)閖ava是單繼承的,它只能繼承于一個類,這樣它的類型就只限于其基類或者基類的基類。但是java可以實(shí)現(xiàn)多個接口,這樣它就可以有很多個接口的類型。就象一個人,它繼承自“脊椎動物”這個類,而“脊椎動物”又繼承自“動物”這個類,因此“張三”是個人,他是一個“脊椎動物”,當(dāng)然他也是一個“動物”。但他可以繼承很多個接口,比如拿駕駛執(zhí)照之后,他就是“駕照持有者”類型,他也可以拿英語六級證書,這樣他就是一個六級證書持有者等等。


      明白這一點(diǎn)之后,我們來看一看 java 的事件機(jī)制。
      java.awt.Button 類有一個 addActionListener(ActionListener l);方法。這個方法傳入的是一個接口類型:ActionListerner,在實(shí)際中,我們需要實(shí)現(xiàn) ActionListener 接口,并且把實(shí)現(xiàn)這個接口的類的對象引用作為參數(shù)傳入。這樣,Button對象就得到了一個 ActionListener 對象,它知道這個 ActionListener 對象有一個 actionPerformed 方法,或者說它有處理 Action 事件的能力,當(dāng) Action 事件發(fā)生時,它就可以調(diào)用這個對象的 actionPerformed 方法。


      比如一般我們會這樣做:
      public class TestButton extends Frame implements ActionListener{
          private Button btn1 = new Button();
          //......
         
          public TestButton(){
              btn.addActionListener(this);
       this.add(btn);
          }
         
          public void actionPerformed(ActionEvent e){
       
          }
      }


      現(xiàn)在我們假設(shè) ActionListener 不是接口,而是一個類。那么我們只能繼承 ActionListener 類,并且重寫 actionPerformed 方法。但是java是單繼承的,如果類繼承了 ActionListener 類,那么它就不能繼承其它的類(Frame 類)了,而不從 Frame 類繼承的話,又怎么創(chuàng)建窗體,怎么把 Button 放到窗體中去呢?



      其實(shí)接口不完全是為了解決 java 的單繼承問題,它在某種程度上可以達(dá)到調(diào)用和實(shí)現(xiàn)細(xì)節(jié)的分離。
      比如說,中國的民用電規(guī)范是一個接口:平均電壓220V、50Hz、Sin 交流電,水力發(fā)電廠、火力發(fā)電廠、核電廠,還有小型的柴油發(fā)電機(jī)如果按這個規(guī)范發(fā)電,則表示它們實(shí)現(xiàn)了這個民用電源的接口;冰箱、電視、洗衣機(jī)等家用電器使用這些電源,表示它們在調(diào)用這個接口。在這里,家用電器不管電從哪里來,只要它符合民用電源的規(guī)范就好,電源也不管它發(fā)的電用于什么工作,只管提供電源。


      再回過頭來看看 Button 的事件機(jī)制。要知道,Button 要保證所有的 action 事件發(fā)生時,程序員都可以在他的代碼中處理它,圖書館管理系統(tǒng)、收銀系統(tǒng)、進(jìn)銷存等等等等等等。而接口就可以做到這一點(diǎn):找一個類實(shí)現(xiàn) ActionListener 接口,并且讓 Button 得到這個類的對象的引用( 調(diào)用 addActionListener 方法),從而當(dāng)Action事件發(fā)生時,button 創(chuàng)建一個包含了事件信息的對象(ActionEvent),然后調(diào)用這個接口對象的方法,到底怎么處理這次事件,這就是實(shí)現(xiàn)接口的類的事情了。在這里,Button 絲毫不了解 actionPerformed 方法中到底干了什么事情,也不應(yīng)該知道。Button 與具體的業(yè)務(wù)邏輯完全分離開了,它可以應(yīng)用到所有的場合。

       


        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多