亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

理解java的多形性

2019-11-18 13:18:50
字體:
來源:轉載
供稿:網友

  “對于面向對象的程序設計語言,多型性是第三種最基本的特征(前兩種是數據抽象和繼續?!?
  
  “多形性”(Polymorphism)從另一個角度將接口從具體的實施細節中分離出來,亦即實現了“是什么”與“怎樣做”兩個模塊的分離。利用多形性的概念,代碼的組織以及可讀性均能獲得改善。此外,還能創建“易于擴展”的程序。無論在項目的創建過程中,還是在需要加入新特性的時候,它們都可以方便地“成長”。
  通過合并各種特征與行為,封裝技術可創建出新的數據類型。通過對具體實施細節的隱藏,可將接口與實施細節分離,使所有細節成為“PRivate”(私有)。這種組織方式使那些有程序化編程背景人感覺頗為舒適。但多形性卻涉及對“類型”的分解。通過上一章的學習,大家已知道通過繼續可將一個對象當作它自己的類型或者它自己的基礎類型對待。這種能力是十分重要的,因為多個類型(從相同的基礎類型中衍生出來)可被當作同一種類型對待。而且只需一段代碼,即可對所有不同的類型進行同樣的處理。利用具有多形性的方法調用,一種類型可將自己與另一種相似的類型區分開,只要它們都是從相同的基礎類型中衍生出來的。這種區分是通過各種方法在行為上的差異實現的,可通過基礎類實現對那些方法的調用。
  在這一章中,大家要由淺入深地學習有關多形性的問題(也叫作動態綁定、推遲綁定或者運行期綁定)。同時舉一些簡單的例子,其中所有無關的部分都已剝除,只保留與多形性有關的代碼。
  
  7.1 上溯造型
  在第6章,大家已知道可將一個對象作為它自己的類型使用,或者作為它的基礎類型的一個對象使用。取得一個對象句柄,并將其作為基礎類型句柄使用的行為就叫作“上溯造型”——因為繼續樹的畫法是基礎類位于最上方。
  但這樣做也會碰到一個問題,如下例所示(若執行這個程序碰到麻煩,請參考第3章的3.1.2小節“賦值”):
  
  
  //: Music.java
  // Inheritance & upcasting
  package c07;
  
  class Note {
  private int value;
  private Note(int val) { value = val; }
  public static final Note
  middleC = new Note(0),
  cSharp = new Note(1),
  cFlat = new Note(2);
  } // Etc.
  
  class Instrument {
  public void play(Note n) {
  System.out.println("Instrument.play()");
  }
  }
  
  // Wind objects are instruments
  // because they have the same interface:
  class Wind extends Instrument {
  // Redefine interface method:
  public void play(Note n) {
  System.out.println("Wind.play()");
  }
  }
  
  public class Music {
  public static void tune(Instrument i) {
  // ...
  i.play(Note.middleC);
  }
  public static void main(String[] args) {
  Wind flute = new Wind();
  tune(flute); // Upcasting
  }
  } ///:~
  
  其中,方法Music.tune()接收一個Instrument句柄,同時也接收從Instrument衍生出來的所有東西。當一個Wind句柄傳遞給tune()的時候,就會出現這種情況。此時沒有造型的必要。這樣做是可以接受的;Instrument里的接口必須存在于Wind中,因為Wind是從Instrument里繼續得到的。從Wind向Instrument的上溯造型可能“縮小”那個接口,但不可能把它變得比Instrument的完整接口還要小。
  
  7.1.1 為什么要上溯造型
  這個程序看起來也許顯得有些希奇。為什么所有人都應該有意忘記一個對象的類型呢?進行上溯造型時,就可能產生這方面的迷惑。而且假如讓tune()簡單地取得一個Wind句柄,將其作為自己的自變量使用,似乎會更加簡單、直觀得多。但要注重:假如那樣做,就需為系統內Instrument的每種類型寫一個全新的tune()。假設按照前面的推論,加入Stringed(弦樂)和Brass(銅管)這兩種Instrument(樂器):
  
  //: Music2.java
  // Overloading instead of upcasting
  
  class Note2 {
  private int value;
  private Note2(int val) { value = val; }
  public static final Note2
  middleC = new Note2(0),
  cSharp = new Note2(1),
  cFlat = new Note2(2);
  } // Etc.
  
  class Instrument2 {
  public void play(Note2 n) {
  System.out.println("Instrument2.play()");
  }
  }
  
  class Wind2 extends Instrument2 {
  public void play(Note2 n) {
  System.out.println("Wind2.play()");
  }
  }
  
  class Stringed2 extends Instrument2 {
  public void play(Note2 n) {
  System.out.println("Stringed2.play()");
  }
  }
  
  class Brass2 extends Instrument2 {
  public void play(Note2 n) {
  System.out.println("Brass2.play()");
  }
  }
  
  public class Music2 {
  public static void tune(Wind2 i) {
  i.play(Note2.middleC);
  }
  public static void tune(Stringed2 i) {
  i.play(Note2.middleC);
  }
  public static void tune(Brass2 i) {
  i.play(Note2.middleC);
  }
  public static void main(String[] args) {
  Wind2 flute = new Wind2();
  Stringed2 violin = new Stringed2();
  Brass2 frenchHorn = new Brass2();
  tune(flute); // No upcasting
  tune(violin);
  tune(frenchHorn);
  }
  } ///:~
  
  這樣做當然行得通,但卻存在一個極大的弊端:必須為每種新增的Instrument2類編寫與類緊密相關的方法。這意味著第一次就要求多得多的編程量。以后,假如想添加一個象tune()那樣的新方法或者為Instrument添加一個新類型,仍然需要進行大量編碼工作。此外,即使忘記對自己的某個方法進行過載設置,編譯器也不會提示任何錯誤。這樣一來,類型的整個操作過程就顯得極難治理,有失控的危險。
  但假如只寫一個方法,將基礎類作為自變量或參數使用,而不是使用那些特定的衍生類,豈不是會簡單得多?也就是說,假如我們能不顧衍生類,只讓自己的代碼與基礎類打交道,那么省下的工作量將是難以估計的。
  這正是“多形性”大顯身手的地方。然而,大多數程序員(非凡是有程序化編程背景的)對于多形性的工作原理仍然顯得有些生疏。
  
  7.2 深入理解
  對于Music.java的困難性,可通過運行程序加以體會。輸出是Wind.play()。這當然是我們希望的輸出,但它看起來似乎并不愿按我們的希望行事。請觀察一下tune()方法:
  
  public static void tune(Instrument i) {
  // ...
  i.play(Note.middleC);
  }
  
  它接收Instrument句柄。所以在這種情況下,編譯器怎樣才能知道Instrument句柄指向的是一個Wind,而不是一個Brass或Stringed呢?編譯器無從得知。為了深入了理解這個問題,我們有必要探討一下“綁定”這個主題。
  
  7.2.1 方法調用的綁定
  將一個方法調用同一個方法主體連接到一起就稱為“綁定”(Binding)。若在程序運行以前執行綁定(由編譯器和鏈接程序,假如有的話),就叫作“早期綁定”。大家以前或許從未聽說過這個術語,因為它在任何程序化語言里都是不可能的。C編譯器只有一種方法調用,那就是“早期綁定”。
  上述程序最令人迷惑不解的地方全與早期綁定有關,因為在只有一個Instrument句柄的前提下,編譯器不知道具體該調用哪個方法。
  解決的方法就是“后期綁定”,它意味著綁定在運行期間進行,以對象的類型為基礎。后期綁定也叫作“動態綁定”或“運行期綁定”。若一種語言實現了后期綁定,同時必須提供一些機制,可在運行期間判定對象的類型,并分別調用適當的方法。也就是說,編譯器此時依然不知道對象的類型,但方法調用機制能自己去調查,找到正確的方法主體。不同的語言對后期綁定的實現方法是有所區別的。但我們至少可以這樣認為:它們都要在對象中安插某些非凡類型的信息。
  Java中綁定的所有方法都采用后期綁定技術,除非一個方法已被聲明成final。這意味著我們通常不必決定是否應進行后期綁定——它是自動發生的。
  為什么要把一個方法聲明成final呢?正如上一章指出的那樣,它能防止其他人覆蓋那個方法。但也許更重要的一點是,它可有效地“關閉”動態綁定,或者告訴編譯器不需要進行動態綁定。這樣一來,編譯器就可為final方法調用生成效率更高的代碼。
  
  7.2.2 產生正確的行為
  知道Java里綁定的所有方法都通過后期綁定具有多形性以后,就可以相應地編寫自己的代碼,令其與基礎類溝通。此時,所有的衍生類都保證能用相同的代碼正常地工作?;蛘邠Q用另一種方法,我們可以“將一條消息發給一個對象,讓對象自行判定要做什么事情。”
  在面向對象的程序設計中,有一個經典的“外形”例子。由于它很輕易用可視化的形式表現出來,所以經常都用它說明問題。但很不幸的是,它可能誤導初學者認為OOP只是為圖形化編程設計的,這種熟悉當然是錯誤的。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲片在线观看| 欧美日韩电影在线观看| 国外视频精品毛片| 日本欧美国产在线| 亚洲最大的免费| 亚洲色图五月天| 中文字幕亚洲一区二区三区五十路| 久久久久久国产精品| 欧美国产中文字幕| 欧美又大又硬又粗bbbbb| 久久久精品免费视频| 欧美国产日韩一区二区三区| 国产精品久久久久久五月尺| 国产成人一区二区三区电影| 久久精品亚洲94久久精品| 伊人久久久久久久久久久久久| 亚洲精品美女久久久| 91欧美精品午夜性色福利在线| 精品久久久久久久久国产字幕| 亚洲精品久久久久久久久久久| 国产有码在线一区二区视频| 欧美成人免费播放| 日韩在线免费观看视频| 另类少妇人与禽zozz0性伦| 狠狠干狠狠久久| 欧美性69xxxx肥| 国产成人拍精品视频午夜网站| 亚洲片在线观看| 国产成人精品a视频一区www| 国产欧美va欧美va香蕉在| 2021久久精品国产99国产精品| 午夜剧场成人观在线视频免费观看| 欧美肥老太性生活视频| 国产精品尤物福利片在线观看| 亚洲国产日韩欧美综合久久| 亚洲成人av片在线观看| 青青久久av北条麻妃黑人| 狠狠色香婷婷久久亚洲精品| 成人日韩在线电影| 亚洲福利视频在线| 精品国产成人在线| 国产日韩精品入口| 欧美国产视频一区二区| 久久伊人91精品综合网站| 国产精品久久99久久| 久久久91精品国产| 超碰91人人草人人干| 久久久女女女女999久久| 日韩一二三在线视频播| 亚洲国产高清自拍| 日韩视频永久免费观看| 夜色77av精品影院| 亚洲国产一区自拍| 精品久久久久久久久久久久| 久久韩剧网电视剧| 91精品成人久久| 亚洲欧美精品中文字幕在线| 91精品国产高清久久久久久久久| 亚洲女人天堂成人av在线| 午夜精品免费视频| 黄色精品一区二区| 一区二区亚洲欧洲国产日韩| 国产日韩欧美在线看| 中文字幕亚洲欧美在线| 亚洲综合大片69999| 免费成人高清视频| 中文字幕在线亚洲| 日韩精品视频免费| 国产欧洲精品视频| 亚洲精品国产精品久久清纯直播| 国产精品高潮粉嫩av| 欧美最顶级丰满的aⅴ艳星| 日韩欧美极品在线观看| 国产精品999999| 成人综合网网址| 97成人超碰免| 中文字幕日韩在线观看| 日韩有码在线电影| 日本a级片电影一区二区| 国产成人中文字幕| 久久亚洲欧美日韩精品专区| 色偷偷88888欧美精品久久久| 另类色图亚洲色图| 国产精品99蜜臀久久不卡二区| 欧美大成色www永久网站婷| 国精产品一区一区三区有限在线| 97av视频在线| 亚洲影视九九影院在线观看| 国产主播精品在线| 国产福利成人在线| 久久久久国产精品www| 日产精品久久久一区二区福利| 国产网站欧美日韩免费精品在线观看| 久久99国产精品久久久久久久久| 国产精品夜间视频香蕉| 国产成人精品av| 欧美在线视频免费播放| 在线观看欧美日韩国产| 亚洲一二在线观看| 91国产在线精品| 91精品在线观看视频| 性欧美xxxx交| 精品女同一区二区三区在线播放| 北条麻妃一区二区三区中文字幕| 亚洲社区在线观看| 日韩av理论片| 国产精品久久久久999| 国产亚洲aⅴaaaaaa毛片| 狠狠躁夜夜躁人人爽超碰91| 日韩有码在线电影| 精品福利一区二区| 668精品在线视频| 久久久久久久久久久免费精品| 亚洲成人a级网| 欧美自拍视频在线| 欧美风情在线观看| 日韩av资源在线播放| 亚洲女同性videos| 欧美香蕉大胸在线视频观看| 美女福利视频一区| 久久大大胆人体| 国产精品v片在线观看不卡| 91免费看视频.| 不卡在线观看电视剧完整版| 日韩电影免费观看中文字幕| 国产亚洲日本欧美韩国| 日本久久久久久久久| 色妞久久福利网| 亚洲精品电影网| 日韩免费观看网站| 韩国精品美女www爽爽爽视频| 久久久久久久999| 久久天天躁狠狠躁夜夜躁| 久久久久久国产免费| 欧美成人精品一区二区三区| 国产999精品久久久影片官网| 91精品在线观| 97在线视频精品| 日韩免费视频在线观看| 国产精品免费网站| 国产欧美日韩最新| 欧美在线国产精品| 欧美午夜精品伦理| 中文字幕久久亚洲| 成人网在线免费看| 国产精品久久久久99| 国产成人精品日本亚洲| 91精品国产色综合久久不卡98| 欧美国产在线视频| 高潮白浆女日韩av免费看| 91黑丝高跟在线| 日韩最新av在线| 亚洲伊人成综合成人网| 欧美激情区在线播放| 国产成人精品免费视频| 亚洲最大成人免费视频| 欧美黑人性视频| 久久99亚洲热视| 日韩av在线免费看| 精品调教chinesegay| 日韩欧美亚洲国产一区| 丝袜亚洲另类欧美重口| 欧美成人中文字幕在线| 国产精品成人播放|