大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動力節(jié)點LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 學習攻略 Java學習 Javase入門教程:深入分析Java多態(tài)

Javase入門教程:深入分析Java多態(tài)

更新時間:2020-03-06 10:32:54 來源:動力節(jié)點 瀏覽2102次


  對于java中多態(tài)概念的理解一直是面試常問的問題,所以今天花了一些時間好好地整理了一下,力求從java虛擬機的角度來分析和理解多態(tài)。


  一、認識多態(tài)


  1、方法調(diào)用


  在Java中,方法調(diào)用有兩類,動態(tài)方法調(diào)用與靜態(tài)方法調(diào)用。


  (1)靜態(tài)方法調(diào)用是指對于類的靜態(tài)方法的調(diào)用方式,是在編譯時刻就已經(jīng)確定好具體調(diào)用方法的情況,是靜態(tài)綁定的。


  (2)動態(tài)方法調(diào)用需要有方法調(diào)用所作用的對象,是在調(diào)用的時候才確定具體的調(diào)用方法,是動態(tài)綁定的。


  我們這里所講的多態(tài)就是后者—動態(tài)方法調(diào)用。


  2、多態(tài)概念


  多態(tài)有兩種:類內(nèi)部之間的多態(tài)和類之間的多態(tài)。我們先看一下標準的概念:


  多態(tài)是面向?qū)ο缶幊陶Z言的重要特性,它允許基類的指針或引用指向派生類的對象,而在具體訪問時實現(xiàn)方法的動態(tài)綁定


  (1)Java的方法重載(類內(nèi)部之間的多態(tài)):就是在類中可以創(chuàng)建多個方法,它們具有相同的名字,但可具有不同的參數(shù)列表、返回值類型。我們舉個例子來解釋,就是一對夫婦生了多胞胎,多胞胎之間外觀相似,其實是不同的孩子。


  (2)Java的方法重寫(父類與子類之間的多態(tài)):子類可繼承父類中的方法,但有時子類并不想原封不動地繼承父類的方法,而是想作一定的修改,這就需要采用方法的重寫。重寫的參數(shù)列表和返回類型均不可修改。我們再舉個例子,就是子承父業(yè),但是兒子有自己想法,對父親得產(chǎn)業(yè)進行再投資的過程。


  二、代碼實現(xiàn)多態(tài)


  1、類內(nèi)部之間得多態(tài):方法重載


Javase入門教程:深入分析Java多態(tài)


  從上述代碼我們可以看到,在類的內(nèi)部可以有相同的方法名,但是有唯一的參數(shù)列表。當然返回類型和修飾符也可以不同。下面我們再看一下類之間的多態(tài)。


  2、類之間的多態(tài):方法重寫


  類之間的多態(tài)其實是有兩種方式:繼承和接口。我們對這兩種方式一個一個說明。


  (1)繼承方式實現(xiàn)多態(tài)


  對于繼承方式我們使用一個例子來解釋,比如說父親可以對自己的房子有處理權(quán),兒子繼承父業(yè)同樣也有處理權(quán)。


  第一步:定義父類


  Javase入門教程:深入分析Java多態(tài)


  第二步:定義子類(大兒子和小兒子)


  Javase入門教程:深入分析Java多態(tài)


  第三步:測試


  Javase入門教程:深入分析Java多態(tài)


  (2)接口方式實現(xiàn)多態(tài)


  接口方式實現(xiàn)繼承方式其實跟上面一樣,只不過把父類變成了接口而已,其他內(nèi)容只有微笑的變化,這里就不演示了,在這里只給出父接口的形式。


Javase入門教程:深入分析Java多態(tài)


  到了這基本上就對多態(tài)形式的代碼實現(xiàn)進行了演示,案例也比較簡單,但是這對我們理解多態(tài)的思想還不夠,我們最主要的還是從虛擬機的角度來分析一下。


  三、分析多態(tài)


  想要深入分析多態(tài),我們需要弄清楚幾個問題。


  1、jvm內(nèi)存


  在上面的代碼中我們其實已經(jīng)看到了,不管是類內(nèi)部之間實現(xiàn)的多態(tài),還是類之間實現(xiàn)的多態(tài),這些方法的名字其實都是一樣的,那我們的程序在運行的時候,底層虛擬機是如何去區(qū)分的呢(java虛擬機實現(xiàn)動態(tài)調(diào)用)?為此我們還是先從java虛擬機講起。


  其實java虛擬機在執(zhí)行java程序的時候,并不是直接運行的,他需要一個過程,我們使用一張圖來看下:


 Javase入門教程:深入分析Java多態(tài)


  上面這張圖已經(jīng)很清晰,也就是說,我們的java文件要想運行,需要通過java編譯器編譯成.class文件,然后通過類裝載器講.class文件裝載到JVM中,最后才是執(zhí)行。而且JVM分了五個區(qū)域,那么在代碼中定義的那些多態(tài)方法存到了哪個地方呢?為此我們還需要對這塊內(nèi)存區(qū)域進行一個分析:

Javase入門教程:深入分析Java多態(tài)


  我給出了一張java7的運行時數(shù)據(jù)區(qū)劃分圖,對于每一個區(qū)域的基本情況我相信你也能看明白。那么我們的多態(tài)方法到底存在了哪呢?沒錯就是后一個方法區(qū)。java堆存的是就是我們建立的一個個實例對象,而方法區(qū)存的就是類的類型信息。


  而且這個方法區(qū)中的類型信息跟在堆中存放的class對象是不同的。在方法區(qū)中,這個class的類型信息只有唯一的實例(所以方法區(qū)是各個線程共享的內(nèi)存區(qū)域),而在堆中可以有多個該class對象。也就是說方法區(qū)的類型信息就是像一個模板,那些class對象就好比通過這些模板創(chuàng)建的一個個實例。


  2、通過例子來分析


  現(xiàn)在我們拿上面的例子來說明一下多態(tài)在java虛擬機中是如何實現(xiàn)的。在測試類中有兩行代碼:


  FathersonA=newSonA();


  FathersonB=newSonB();


  當程序運行到FathersonA=newSonA()這里就出現(xiàn)了多態(tài),這是因為編譯時看到Father,但是運行時new出來一個SonA類,兩種類型還不一樣。那么這些代碼在運行的時候在內(nèi)存中是如何保存的呢?


  (1)FathersonA是一個引用類型,存在了java棧中的本地方法表中了。


  (2)newSonA其實創(chuàng)建了一個實例對象,存儲在了java堆中。


  (3)SonA的類型數(shù)據(jù)存在了方法區(qū)中


  我們在內(nèi)存中看一下:


 Javase入門教程:深入分析Java多態(tài)


  reference中存儲的就是對象在堆中的實際地址,在堆中存儲的對象信息中包含了在方法區(qū)中的相應(yīng)類型數(shù)據(jù)。流程很簡單,我們梳理一下:


  第一步:虛擬機通過reference(Father的引用)查詢java棧中的本地變量表,得到堆中的對象類型數(shù)據(jù)的指針,


  第二步:通過到對象的指針找到方法區(qū)中的對象類型數(shù)據(jù)


  第三步:查詢方法表定位到實際類(SonA類)的方法運行。


  好了,到第三步我們知道,其實是通過方法表來定位到實際運行的方法的。下面我們再來看看這個方法表是什么。


  3、方法表


  方法表肯定是存在于方法區(qū)中的,它是實現(xiàn)多態(tài)的關(guān)鍵所在,這里面保存的就是實例方法的引用,而且是直接引用。java虛擬機在執(zhí)行程序的時候就是通過這個方法表來確定運行哪一個多態(tài)方法的。


  我們通過上面的例子,來演示一下父子類在方法表中是如何保存的:


Javase入門教程:深入分析Java多態(tài)


  很明顯每一個類都會有一個方法表,子類中不同的方法指向不同的類型信息。繼承自O(shè)bject的就指向Object,繼承自Father的就指向Father(也就是包含了父類的方法dealHouse)。


  可能我們到這就迷糊了,既然子類的dealHouse方法其實是父類Father的,那么為什么會執(zhí)行子類的dealHouse方法呢?別著急往下看。這是java虛擬機區(qū)分多態(tài)方法(實現(xiàn)動態(tài)調(diào)用)的精華所在。


  當Son類的方法表會有一個指向Father類dealHouse方法的指針,同時也有一個指向自己dealHouse方法的指針,這時候,新的數(shù)據(jù)會覆蓋原有的數(shù)據(jù),也就是說原來指向Father.dealHouse的那個引用會被替換成指向Son.dealHouse的引用(占據(jù)原來表中的位置)


  注意:


  上述講述的其實是對繼承實現(xiàn)的多態(tài)的一種分析,對接口實現(xiàn)的,會有著不一樣的理解。Java虛擬機對于接口方法的調(diào)用是采用搜索方法表的方式,如,要在Father接口的方法表中找到dealHouse()方法,必須搜索Father的整個方法表。從效率上來說,接口方法的調(diào)用總是慢于類方法的調(diào)用的。


  以上就是對java多態(tài)的分析與理解,總結(jié)一下就是說,類調(diào)用和接口調(diào)用兩種方式區(qū)分不同方法是不一樣的,類調(diào)用是根據(jù)多態(tài)方法在方法表中的位移量,而接口調(diào)用是根據(jù)搜索整個方法表來實現(xiàn)的。


      以上就是動力節(jié)點Java培訓機構(gòu)小編介紹的“Javase入門教程:深入分析Java多態(tài)”的內(nèi)容,希望對大家有幫助,如有疑問,請在線咨詢,有專業(yè)老師隨時為你服務(wù)。


提交申請后,顧問老師會電話與您溝通安排學習

免費課程推薦 >>
技術(shù)文檔推薦 >>
主站蜘蛛池模板: 国产一级毛片国语版 | 国产精品原创永久在线观看 | 精品久久久久久久九九九精品 | 黄色成人在线 | 91久久九九精品国产综合 | 国产精品99一区二区三区 | 91精品91久久久 | 手机在线中文字幕 | 日韩一区二区三区视频在线观看 | 最新亚洲精品国自产在线 | 狠狠的色| 婷婷视频网站 | 国产成人综合视频 | 久久精品美女久久 | 久一视频在线 | 久久久青草青青国产亚洲免观 | 亚洲黄色录像 | 天天干天天拍天天射天天添天天爱 | 亚洲视频 欧美视频 | 黄片毛片在线看 | 我就色色综合网 | 日本一区二区三区在线观看 | 狠狠综合 | 欧美α片无限看在线观看免费 | 日本不卡免费在线 | 天天操天天添 | 福利视频在线播放 | 国产亚洲精品看片在线观看 | 九九影片重口味 | 一本大道香蕉中文在线高清 | 日韩精品视频观看 | 欧美一级a毛片人人dvd | 综合另类小说色区色噜噜 | 久射网| 亚洲婷婷综合中文字幕第一页 | 中文久久 | 成人短视频网站 | 中文在线1区二区六区 | 欧美一级黄色片在线观看 | 成人免费久久精品国产片久久影院 | 国产精品图片 |