Java基礎複習(五)

來源:互聯網
上載者:User

標籤:

1、 介面是否可繼承介面? 抽象類別是否可實現(implements)介面? 抽象類別是否可繼承具體類(concrete class)? 抽象類別中是否可以有靜態main方法?
  介面可以繼承介面。抽象類別可以實現(implements)介面,抽象類別是否可繼承具體類。抽象類別中可以有靜態main方法。
  備忘:只要明白了介面和抽象類別的本質和作用,這些問題都很好回答,你想想,如果你是java語言的設計者,你是否會提供這樣的支援,如果不提供的話,有什麼理由嗎?如果你沒有道理不提供,那答案就是肯定的了。只有記住抽象類別與普通類的唯一區別就是不能建立執行個體對象和允許有abstract方法。

2、 寫clone()方法時,通常都有一行代碼,是什嗎?
  clone 有預設行為,super.clone();因為首先要把父類中的成員複製到位,然後才是複製自己的成員。

3、 物件導向的特徵有哪些方面

  電腦軟體系統是現實生活中的業務在電腦中的映射,而現實生活中的業務其實就是一個個對象協作的過程。物件導向編程就是按現實業務一樣的方式將程式碼按一個個對象進行組織和編寫,讓電腦系統能夠識別和理解用對象方式組織和編寫的程式碼,這樣就可以把現實生活中的業務對象映射到電腦系統中。 物件導向的程式設計語言有封裝、繼承 、抽象、多態等4個主要的特徵。

  封裝: 封裝是保證軟體組件具有優良的模組性的基礎,封裝的目標就是要實現軟體組件的“高內聚、低耦合”,防止程式相互依賴性而帶來的變動影響。在物件導向的程式設計語言中,對象是封裝的最基本單位,物件導向的封裝比傳統語言的封裝更為清晰、更為有力。物件導向的封裝就是把描述一個對象的屬性和行為的代碼封裝在一個“模組”中,也就是一個類中,屬性用變數定義,行為用方法進行定義,方法可以直接存取同一個對象中的屬性。通常情況下,只要記住讓變數和訪問這個變數的方法放在一起,將一個類中的成員變數全部定義成私人的,只有這個類自己的方法才可以訪問到這些成員變數,這就基本上實現對象的封裝,就很容易找出要分配到這個類上的方法了,就基本上算是會物件導向的編程了。把握一個原則:把對同一事物進行操作的方法和相關的方法放在同一個類中,把方法和它操作的資料放在同一個類中。 例如,人要在黑板上畫圓,這一共涉及三個對象:人、黑板、圓,畫圓的方法要分配給哪個對象呢?由於畫圓需要使用到圓心和半徑,圓心和半徑顯然是圓的屬性,如果將它們在類中定義成了私人的成員變數,那麼,畫圓的方法必須分配給圓,它才能訪問到圓心和半徑這兩個屬性,人以後只是調用圓的畫圓方法、表示給圓發給訊息而已,畫圓這個方法不應該分配在人這個對象上,這就是物件導向的封裝性,即將對象封裝成一個高度自治和相對封閉的個體,對象狀態(屬性)由這個對象自己的行為(方法)來讀取和改變。一個更便於理解的例子就是,司機將火車刹住了,刹車的動作是分配給司機,還是分配給火車,顯然,應該分配給火車,因為司機自身是不可能有那麼大的力氣將一個火車給停下來的,只有火車自己才能完成這一動作,火車需要調用內部的離合器和刹車片等多個器件協作才能完成刹車這個動作,司機刹車的過程只是給火車發了一個訊息,通知火車要執行刹車動作而已。

  抽象: 抽象就是找出一些事物的相似和共性之處,然後將這些事物歸為一個類,這個類只考慮這些事物的相似和共性之處,並且會忽略與當前主題和目標無關的那些方面,將注意力集中在與當前目標有關的方面。例如,看到一隻螞蟻和大象,你能夠想象出它們的相同之處,那就是抽象。抽象包括行為抽象和狀態抽象兩個方面。例如,定義一個Person類,如下: class Person {   String name;   int age; } 人本來是很複雜的事物,有很多方面,但因為當前系統只需要瞭解人的姓名和年齡,所以上面定義的類中只包含姓名和年齡這兩個屬性,這就是一種抽像,使用抽象可以避免考慮一些與目標無關的細節。我對抽象的理解就是不要用顯微鏡去看一個事物的所有方面,這樣涉及的內容就太多了,而是要善於劃分問題的邊界,當前系統需要什麼,就只考慮什麼。

  繼承: 在定義和實現一個類的時候,可以在一個已經存在的類的基礎之上來進行,把這個已經存在的類所定義的內容作為自己的內容,並可以加入若干新的內容,或修改原來的方法使之更適合特殊的需要,這就是繼承。繼承是子類自動共用父類資料和方法的機制,這是類之間的一種關係,提高了軟體的可重用性和可擴充性。

  多態: 多態是指程式中定義的引用變數所指向的具體類型和通過該引用變數發出的方法調用在編程時並不確定,而是在程式運行期間才確定,即一個引用變數倒底會指向哪個類的執行個體對象,該引用變數發出的方法調用到底是哪個類中實現的方法,必須在由程式運行期間才能決定。因為在程式運行時才確定具體的類,這樣,不用修改來源程式代碼,就可以讓引用變數綁定到各種不同的類實現上,從而導致該引用調用的具體方法隨之改變,即不修改程式碼就可以改變程式運行時所綁定的具體代碼,讓程式可以選擇多個運行狀態,這就是多態性。多態性增強了軟體的靈活性和擴充性。例如,下面代碼中的UserDao是一個介面,它定義引用變數userDao指向的執行個體對象由daofactory.getDao()在執行的時候返回,有時候指向的是UserJdbcDao這個實現,有時候指向的是UserHibernateDao這個實現,這樣,不用修改原始碼,就可以改變userDao指向的具體類實現,從而導致userDao.insertUser()方法調用的具體代碼也隨之改變,即有時候調用的是UserJdbcDao的insertUser方法,有時候調用的是UserHibernateDao的insertUser方法: UserDao userDao = daofactory.getDao();  userDao.insertUser(user);

4、 java中實現多態的機制是什嗎?

  靠的是父類或介面定義的引用變數可以指向子類或具體實作類別的執行個體對象,而程式調用的方法在運行期才動態綁定,就是引用變數所指向的具體執行個體對象的方法,也就是記憶體裡正在啟動並執行那個對象的方法,而不是引用變數的類型中定義的方法。

5、 abstract class和interface有什麼區別?  

  含有abstract修飾符的class即為抽象類別,abstract 類不能建立執行個體對象。含有abstract方法的類必須定義為abstract class,abstract class類中的方法不必是抽象的。abstract class類中定義抽象方法必須在具體(Concrete)子類中實現,所以,不能有抽象構造方法或抽象靜態方法。如果的子類沒有實現抽象父類中的所有抽象方法,那麼子類也必須定義為abstract類型。 介面(interface)可以說成是抽象類別的一種特例,介面中的所有方法都必須是抽象的。介面中的方法定義預設為public abstract類型,介面中的成員變數類型預設為public static final。

  下面比較一下兩者的文法區別:

    1.抽象類別可以有構造方法,介面中不能有構造方法。

    2.抽象類別中可以有普通成員變數,介面中沒有普通成員變數

    3.抽象類別中可以包含非抽象的普通方法,介面中的所有方法必須都是抽象的,不能有非抽象的普通方法。

    4. 抽象類別中的抽象方法的訪問類型可以是public,protected和(預設類型,雖然 eclipse下不報錯,但應該也不行),但介面中的抽象方法只能是public類型的,並且預設即為public abstract類型。

    5. 抽象類別中可以包含靜態方法,介面中不能包含靜態方法

    6. 抽象類別和介面中都可以包含靜態成員變數,抽象類別中的靜態成員變數的訪問類型可以任意,但介面中定義的變數只能是public static final類型,並且預設即為public static final類型。

    7. 一個類可以實現多個介面,但只能繼承一個抽象類別。  

  下面接著再說說兩者在應用上的區別:

    介面更多的是在系統架構設計方法發揮作用,主要用於定義模組之間的通訊契約。而抽象類別在代碼實現方面發揮作用,可以實現代碼的重用,例如,模板方法設計模式是抽象類別的一個典型應用,假設某個項目的所有Servlet類都要用相同的方式進行許可權判斷、記錄訪問日誌和處理異常,那麼就可以定義一個抽象的基類,讓所有的Servlet都繼承這個抽象基類,在抽象基類的service方法中完成許可權判斷、記錄訪問日誌和處理異常的代碼,在各個子類中只是完成各自的商務邏輯代碼,虛擬碼如下:

    public abstract class BaseServlet extends HttpServlet

    {   

      public final void service(HttpServletRequest request, HttpServletResponse response) throws IOExcetion,ServletException   

      {   

         記錄訪問日誌    

        進行許可權判斷 if(具有許可權)

        {  

          try  {   

            doService(request,response);

          }  catch(Excetpion e)  {    記錄異常資訊  } }   }   

    protected abstract void doService(HttpServletRequest request, HttpServletResponse response) throws IOExcetion,ServletException; 

    //注意存取權限定義成protected,顯得既專業,又嚴謹,因為它是專門給子類用的 }

    public class MyServlet1 extends BaseServlet

    {

      protected void doService(HttpServletRequest request, HttpServletResponse response) throws IOExcetion,ServletException   

      {    本Servlet只處理的具體商務邏輯代碼   }

    }

  父類方法中間的某段代碼不確定,留給子類幹,就用模板方法設計模式。 備忘:這道題的思路是先從總體解釋抽象類別和介面的基本概念,然後再比較兩者的文法細節,最後再說兩者的應用區別。比較兩者文法細節區別的條理是:先從一個類中的構造方法、普通成員變數和方法(包括抽象方法),靜態變數和方法,繼承性等6個方面逐一去比較回答,接著從第三者繼承的角度的回答,特別是最後用了一個典型的例子來展現自己深厚的技術功底。

6、 abstract的method是否可同時是static,是否可同時是native,是否可同時是synchronized?
  abstract的method 不可以是static的,因為抽象的方法是要被子類實現的,而static與子類扯不上關係!
  native方法表示該方法要用另外一種依賴平台的程式設計語言實現的,不存在著被子類實現的問題,所以,它也不能是抽象的,不能與abstract混用。

  例如,FileOutputSteam類要硬體打交道,底層的實現用的是作業系統相關的api實現,例如,在windows用c語言實現的,所以,查看jdk 的原始碼,可以發現  FileOutputStream的open方法的定義如下: private native void open(String name) throws FileNotFoundException;如果我們要用java調用別人寫的c語言函數,我們是無法直接調用的,我們需要按照java的要求寫一個c語言的函數,又我們的這個c語言函數去調用別人的c語言函數。由於我們的c語言函數是按java的要求來寫的,我們這個c語言函數就可以與java對接上,java那邊的對接方式就是定義出與我們這個c函數相對應的方法,java中對應的方法不需要寫具體的代碼,但需要在前面聲明native。
  關於synchronized與abstract合用的問題,我覺得也不行,因為在我幾年的學習和開發中,從來沒見到過這種情況,並且我覺得synchronized應該是作用在一個具體的方法上才有意義。而且,方法上的synchronized同步所使用的同步鎖對象是this,而抽象方法上無法確定this是什麼。

 

Java基礎複習(五)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.