欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中構(gòu)造器內(nèi)部的多態(tài)方法的行為實例分析

 更新時間:2019年10月28日 11:43:42   作者:Alan_Xiang  
這篇文章主要介紹了Java中構(gòu)造器內(nèi)部的多態(tài)方法的行為,結(jié)合實例形式分析了java構(gòu)造器內(nèi)部多態(tài)方法相關原理、功能及操作技巧,需要的朋友可以參考下

本文實例講述了Java中構(gòu)造器內(nèi)部的多態(tài)方法的行為操作。分享給大家供大家參考,具體如下:

這篇文章主要討論的是,若在一個構(gòu)造器中調(diào)用正在構(gòu)造的對象的某個動態(tài)綁定的方法時會出現(xiàn)的情況。在此之前,我們需要知道構(gòu)造器是如何在復雜的層次結(jié)構(gòu)中運作的,盡管構(gòu)造方法并不具有多態(tài)性,因為它們實際上是static方法,只不過是隱式聲明的static。

復雜層次結(jié)構(gòu)中構(gòu)造器的調(diào)用順序

基類的構(gòu)造器總是在導出類的構(gòu)造過程中被調(diào)用,而且按照繼承層次逐漸向上鏈接,以使每個基類的構(gòu)造器都能得到調(diào)用。這樣做是因為,在Java類中,我們通常將字段設置為private類型,也就是說,在子類中通常無法直接訪問基類的字段,那么只有通過調(diào)用基類的構(gòu)造器才能對基類對象的元素進行初始化,那么就必須保證所有的構(gòu)造器都得到調(diào)用,這樣才能正確地構(gòu)造完整的對象。下面的例1展示了包含有組合與繼承關系的各類中構(gòu)造器的調(diào)用順序: 

例1:

class Meal {
   Meal() { System.out.println("Meal()"); }
}
class Bread {
   Bread() { System.out.println("Bread()"); }
}
class Cheese {
   Cheese() { System.out.println("Cheese()"); }
}
class Lettuce {
   Lettuce() { System.out.println("Lettuce()"); }
}
class Lunch extends Meal {
   Lunch() { System.out.println("Lunch()"); }
}
class PortableLunch extends Lunch {
   PortableLunch() { System.out.println("PortableLunch()");}
}
public class Sandwich extends PortableLunch {
   private Bread b = new Bread();
   private Cheese c = new Cheese();
   private Lettuce l = new Lettuce();
   public Sandwich() { System.out.println("Sandwich()"); }
   public static void main(String[] args) {
    new Sandwich();
   }
}

例1反映了關于Meal、Lunch和Sandwich之間三層繼承關系(不包含Object類),以及Bread、Cheese和Lettuce與Sandwich的組合關系。在main函數(shù)中創(chuàng)建一個Sandwich對象后,我們就可以看到輸出結(jié)果: 

這說明在復雜的層次結(jié)構(gòu)中構(gòu)造器的調(diào)用遵從的順序為: 

** 1、調(diào)用基類構(gòu)造器。這個步驟會不斷地反復遞歸下去,首先是構(gòu)造這種層次結(jié)構(gòu)的根,然后是下一層導出類,等等,直到最低層的導出類;
2、按聲明的順序調(diào)用成員的初始化方法;
3、調(diào)用導出類構(gòu)造器的主體。**

構(gòu)造器內(nèi)部的多態(tài)方法的行為

那么,現(xiàn)在我們回到文章開頭提到的問題,若在一個構(gòu)造器中調(diào)用正在構(gòu)造的對象的某個動態(tài)綁定的方法,會出現(xiàn)什么情況呢?我們知道,動態(tài)綁定(或后期綁定)的方法的調(diào)用是在運行時才決定的,因為對象在程序運行之前無從得知它自己到底是基類的對象,還是某個導出類的對象。如果在基類的構(gòu)造器內(nèi)部調(diào)用某個動態(tài)綁定方法,該方法是被導出類覆蓋的,那么這便可能產(chǎn)生難以預料的后果,因為該導出類的對象還未被完全構(gòu)造,但它的方法卻被調(diào)用了。我們可以通過例2看到問題所在:

例2:

class Glyph {
   void draw() { System.out.println("Glyph.draw()"); }
   Glyph() {
    System.out.println("Glyph() before draw()");
    draw();
    System.out.println("Glyph() after draw()");
   }
}  
class RoundGlyph extends Glyph {
   private int radius = 1;
   RoundGlyph(int r) {
    radius = r;
    System.out.println("RoundGlyph.RoundGlyph(), radius = " + radius);
   }
   void draw() {
    System.out.println("RoundGlyph.draw(), radius = " + radius);
   }
}  
public class PolyConstructors {
   public static void main(String[] args) {
    new RoundGlyph(5);
   }
}

運行結(jié)果:

在運行結(jié)果中,我們看到,基類Glyph的構(gòu)造器中調(diào)用了被子類RoundGlyph覆蓋的draw()方法,并且輸出了radius=0,這顯然是一個錯誤,因為這個“0”是在其他任何事物發(fā)生之前,系統(tǒng)分配給對象的存儲空間的初始值——二進制的零,而非我們想要設定的初始值“1”。這是因為,我們在創(chuàng)建子類(RoundGlyph)對象時會先調(diào)用基類(Glyph)的構(gòu)造器構(gòu)造基類對象,而在基類的構(gòu)造器中卻調(diào)用了被子類覆蓋的動態(tài)綁定的方法(draw()),而這個方法所操縱的可能是子類中的還未進行初始化的成員(radius),這便會招致災難,盡管編譯器并沒有報錯。

因此,在編寫構(gòu)造器中有一條有效的準則:“用盡可能簡單的方法使對象進入正常狀態(tài);如果可以的話,避免調(diào)用其他方法”。在構(gòu)造器中,唯一能夠安全調(diào)用的是基類中的final方法(包括private方法),因為這些方法不能被子類覆蓋,也就不會出現(xiàn)上述的問題。

更多java相關內(nèi)容感興趣的讀者可查看本站專題:《Java面向?qū)ο蟪绦蛟O計入門與進階教程》、《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總

希望本文所述對大家java程序設計有所幫助。

相關文章

  • MybatisPlus開啟、關閉二級緩存方法

    MybatisPlus開啟、關閉二級緩存方法

    本文主要介紹了MybatisPlus開啟、關閉二級緩存方法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • JVM內(nèi)存參數(shù)配置詳解

    JVM內(nèi)存參數(shù)配置詳解

    本文主要介紹了JVM內(nèi)存參數(shù)配置詳解,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • Spring?異步接口返回結(jié)果的四種方式

    Spring?異步接口返回結(jié)果的四種方式

    這篇文章主要介紹了Spring?異步接口返回結(jié)果的四種方式,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下
    2022-08-08
  • 詳解JDBC的概念及獲取數(shù)據(jù)庫連接的5種方式

    詳解JDBC的概念及獲取數(shù)據(jù)庫連接的5種方式

    Java?DataBase?Connectivity是將Java與SQL結(jié)合且獨立于特定的數(shù)據(jù)庫系統(tǒng)的應用程序編程接口,一種可用于執(zhí)行SQL語句的JavaAPI。本文主要介紹了JDBC的概念及獲取數(shù)據(jù)庫連接的5種方式,需要的可以參考一下
    2022-09-09
  • SpringBoot整合模板引擎過程代碼實例

    SpringBoot整合模板引擎過程代碼實例

    這篇文章主要介紹了SpringBoot整合模板引擎過程代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-07-07
  • Java CharacterEncodingFilter過濾器的理解和配置案例詳解

    Java CharacterEncodingFilter過濾器的理解和配置案例詳解

    這篇文章主要介紹了Java CharacterEncodingFilter過濾器的理解和配置案例詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • Java使用UTF-8或GBK編碼后還是亂碼問題的解決辦法

    Java使用UTF-8或GBK編碼后還是亂碼問題的解決辦法

    在java中處理字符時,經(jīng)常會發(fā)生亂碼,下面這篇文章主要給大家介紹了關于Java使用UTF-8或GBK編碼后還是亂碼問題的解決辦法,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2023-05-05
  • Spring中的@Transactional事務失效場景解讀

    Spring中的@Transactional事務失效場景解讀

    這篇文章主要介紹了Spring中的@Transactional事務失效場景解讀,如果Transactional注解應用在非public 修飾的方法上,Transactional將會失效此方法會檢查目標方法的修飾符是否為 public,不是 public則不會獲取@Transactional 的屬性配置信息,需要的朋友可以參考下
    2023-12-12
  • 使用springmvc運行流程分析,手寫spring框架嘗試

    使用springmvc運行流程分析,手寫spring框架嘗試

    這篇文章主要介紹了使用springmvc運行流程分析,手寫spring框架嘗試,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • 深入XPath的詳解以及Java示例代碼分析

    深入XPath的詳解以及Java示例代碼分析

    本篇文章是對XPath進行了詳細的分析介紹,需要的朋友參考下
    2013-06-06

最新評論