日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

方法重写(Java篇)

發(fā)布時間:2023/12/15 java 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 方法重写(Java篇) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

很多人會問:

  • 本來有的方法為什么要再寫一遍?
  • 重寫的意義是什么?
  • 兩個方法調(diào)用的時候不會有沖突嗎?
  • 為什么不再新建一個全新的方法呢?
  • 當一個子類繼承一個父類時,它同時繼承了父類的屬性和方法。子類可以直接使用父類的屬性和方法,如果父類的方法不能滿足子類的需求,則可以在子類中對父類的方法進行重寫(或覆蓋)。

    在方法重寫時,如果子類需要引用父類中原有的方法,可以使用 super 關(guān)鍵字。當子類重寫父類方法后,在子類對象使用該方法時,會執(zhí)行子類中重寫的方法。如果子類型重寫了父類型的同名方法,那么只知道父類型的定義就可以調(diào)用子類型的方法了

    實際應(yīng)用中,用得最多的一種運行時多態(tài),就是用只知道父類型(可能是類,更多的可能是接口)的定義,這樣只能調(diào)用父類型的方法(這在大型軟件里很常用,父類型和子類型可能是不同的人編寫的,以利于協(xié)作編程)。

    簡約規(guī)則:
    在子類重寫父類方法時,需要遵守以下幾個重寫規(guī)則。
    □ 重寫方法名、參數(shù)和返回類型必須與父類方法定義一致。
    □ 重寫方法的修飾符不能比父類方法嚴格。例如父類方法時用 public 修飾,那么重寫方法不能使用protected或private等修飾。
    □ 重寫方法如果有throws 定義,那么重寫方法throws 的異常類型可以是父類方法throws的異常類型及其子類類型。
    方法在重寫時有很多細節(jié)需要注意,否則即使定義了方法,也可能不屬于重寫,不具有方法重寫之后的特征。

    重寫的規(guī)則:
    1、重寫規(guī)則之一:
    訪問修飾符的限制一定要不小于被重寫方法的訪問修飾符

    比如:Object類有個toString()方法, 開始重寫這個方法的時候我們總?cè)菀淄汸ublic修飾符, 出錯的原因就是:沒有加任何訪問修飾符的方法具有包訪問權(quán)限, Default訪問權(quán)限小于Public訪問權(quán)限, 所以編譯器出錯。

    2、重寫規(guī)則之二:
    參數(shù)列表必須與被重寫方法的相同。
    重載的時候,方法名要一樣,但是參數(shù)類型和個數(shù)不一樣,返回值類型可以相同也可以不相同。

    3、重寫規(guī)則之三:
    C-1:返回類型必須與被重寫方法的返回類型相同。
    父類方法A:void catch(){} 子類方法 B:int catch(){} 兩者雖然參數(shù)相同, 返回類型不同, 所以不是重寫。
    父類方法A:int catch(){} 子類方法 B:long catch(){} 返回類型雖然兼容父類, 但是不同就是不同, 所以不是重寫。

    C-1補足1: 如果在沒有加注@Override的情況下, 方法名和參數(shù)列表完全相同,且滿足規(guī)則A的情況下, 返回值類型必須完全一致的情況下、才不會出現(xiàn)編譯錯誤(即為該方法為強制重寫方法)。如果以上條件中參數(shù)列表不同,且返回值類型不同這樣編譯并不會出現(xiàn)錯誤(這個方法為在子類的新方法,且不是重寫方法)。// 2016/11/21 19:44 bluetata 追記標注補足1(下接博文后追記)C-1補足2: 當子類的方法重寫或?qū)崿F(xiàn)父類的方法時, 方法的后置條件(即方法的返回值)要比父類更嚴格。[參照2]// 2016/11/22 追記

    即:如果重寫方法的參數(shù)列表和方法名相同,且其他條件滿足的情況下,方法的返回值為父類的子類,那么該方法也為重寫方法

    package com.ibm.dietime1943.test;

    public class Computer {
    public Computer sale() { return new Computer(); }

    public HP make() { return new HP(); }
    }

    class IBM extends Computer {

    @Override
    public IBM sale() { return new IBM(); }
    }

    class HP extends Computer {

    @Override
    public Computer make() { return new Computer(); } // compilation error
    }

    4、重寫規(guī)則之四:
    重寫方法不能拋出新的異常或者比被重寫方法聲明的檢查異常更廣的檢查異常。但是可以拋出更少,更有限或者不拋出異常。

    舉個簡單的例子:父類異常好比父親偷盜搶掠、那么兒子不能比父親更壞、要學好、自然異常就要少。雖然舉得例子與社會主義核心價值觀有沖突、但是比較形象。// 2016/12/10 10:55 bluetata 追記 add

    5、重寫規(guī)則之五:
    如果一個方法不能被繼承, 則不能重寫它。
    比較典型的就是父類的private方法。因為private說明該方法對子類是不可見的, 子類再寫一個同名的方法并不是對父類方法進行復(fù)寫(Override), 而是重新生成一個新的方法, 也就不存在多態(tài)的問題了。同理也可以解釋final, 因為方法同樣是不可覆蓋的。

    6、重寫規(guī)則之六:
    不能重寫被標識為final的方法。

    // 2016/12/01 17:05 bluetata 追記 add Startfinal方法可以被繼承, 但是不能被重寫, 一個方法如果被final修飾, 那么也就意味著, 這個方法不會被改動(聲明一個final方法的主要目的是防止方法的內(nèi)容被修改)。// 2016/12/01 17:12 bluetata 追記 add End

    7、重寫規(guī)則之七:
    靜態(tài)方法不能被重寫。

    《JAVA編程思想》中多次的提到:方法是靜態(tài)的、他的行為就不具有多態(tài)性。靜態(tài)方法是與類、而非單個對象相關(guān)聯(lián)的。

    父類的普通方法可以被繼承和重寫,不多作解釋,如果子類繼承父類,而且子類沒有重寫父類的方法,但是子類會有從父類繼承過來的方法。靜態(tài)的方法可以被繼承,但是不能重寫。如果父類中有一個靜態(tài)的方法,子類也有一個與其方法名,參數(shù)類型,參數(shù)個數(shù)都一樣的方法,并且也有static關(guān)鍵字修飾,那么該子類的方法會把原來繼承過來的父類的方法隱藏,而不是重寫。通俗的講就是父類的方法和子類的方法是兩個沒有關(guān)系的方法,具體調(diào)用哪一個方法是看是哪個對象的引用;這種父子類方法也不在存在多態(tài)的性質(zhì)。《JAVA編程思想》:只有普通的方法調(diào)用可以是多態(tài)的,靜態(tài)方法是與類而不是與某個對象相關(guān)聯(lián)。

    // 2016/11/22 16:45 bluetata 追記 add Start

    補足1:父類的靜態(tài)方法不能被子類覆蓋為非靜態(tài)方法。

    子類可以定義于父類的靜態(tài)方法同名的靜態(tài)方法、以便在子類中隱藏父類的靜態(tài)方法(滿足覆蓋約束)、而且Java虛擬機把靜態(tài)方法和所屬的類綁定、而把實例方法和所屬的實例綁定。如果在上記的方法上追記@Override注解的話、該方法會出編譯錯誤。應(yīng)為該方法實際不是重寫方法。

    補足2:父類的非靜態(tài)方法不能被子類覆蓋為靜態(tài)方法。

    // 2016/11/22 16:45 bluetata 追記 add End

    補足3:面試可能會遇到的此處相關(guān)問題(與靜態(tài)相關(guān))

    1、abstract方法能否被static修飾?不能被static修飾, 因為抽象方法要被重寫、而static和子類占不到邊、即上述。// 2016/12/06 20:59 bluetata 追記反過來也一樣static方法一定不能被abstract方法修飾, static不屬于對象而屬于類, static方法可以被類直接調(diào)用(抽象方法需要被實例才能被調(diào)用, 這里說的實例是實現(xiàn)的意思,也就是重寫后實現(xiàn)其方法), 這樣注定了static方法一定有方法體, 不能是沒有方法體的抽象方法(被abstract修飾) // 2018/07/10 18:17 bluetata 追記2、為什么靜態(tài)方法不能被覆蓋? // 2016/12/15 午后 追記可以參看上面從java編程思想摘出的話、另外在總結(jié)下:覆蓋依賴于類的實例,而靜態(tài)方法和類實例并沒有什么關(guān)系。而且靜態(tài)方法在編譯時就已經(jīng)確定,而方法覆蓋是在運行時確定的(動態(tài)綁定)(也可以說是java多態(tài)體現(xiàn)在運行時、而static在編譯時、與之相悖)。3、構(gòu)造方法能否被重寫、為什么? // 2016/12/15 晚 追記不能、構(gòu)造方法是隱式的static方法、同問題2。其實這個問題回答切入點很多、首先構(gòu)造方法無返回值、方法名必須和所在類名相同、這一點就必殺了子類無法重寫父類構(gòu)造方法。另外多態(tài)方面、重寫是多態(tài)的一種提現(xiàn)方式、假設(shè)在子類重寫了構(gòu)造方法是成立的、那么子類何談實例成父類。另外重要得一點、子類可以使用super()調(diào)用父類的構(gòu)造方法、且必須放在子類構(gòu)造方法內(nèi)的第一行。 請參看另一篇博文: <<Super和this用法,對象的加載順序>>4、靜態(tài)方法為什么不能訪問非靜態(tài)變量或方法? // 2018/07/10 午后追記對于前面123問題理解后, 問題4也不難理解, 還是引用下《JAVA編程思想》:靜態(tài)方法是與類而不是與某個對象相關(guān)聯(lián) 用static修飾的成員屬于類, 非static修飾的成員屬于實例對象, 也就是類可以直接調(diào)用靜態(tài)成員, 這樣假設(shè)如果類直接調(diào)用了靜態(tài)成員, 而靜態(tài)成員調(diào)用了非靜態(tài)變量或方法, 這樣在內(nèi)存中是找不到該非靜態(tài)變量方法的, 因為靜態(tài)方法需要創(chuàng)建對象后才可調(diào)用.另外通過類加載說明: 類的加載全過程:加載->驗證->準備->解析->初始化 在這里加載到解析階段都是JVM進行主導(dǎo),而在初始化階段才是真正java執(zhí)行代碼的階段. static成員在初始化階段之前會被加載到方法區(qū)中, 并且進行初始化賦值等操作,并且分配內(nèi)存, 而非static成員確是在加載后解析后的初始化階段才會被"加載"分配內(nèi)存, 也就是代碼中使用new進行創(chuàng)建實例的時候, 這樣也就驗證了 類可以直接調(diào)用static成員沒有問題, 而直接調(diào)用非static的成員就會出問題, 因為違背了java加載初始化的邏輯.

    注意: 如果static調(diào)用非static成員 編譯器會出現(xiàn) No enclosing instance of type * is accessible 異常錯誤.

    XX01、重寫規(guī)則補足:

    補足1:父類的抽象方法可以被子類通過兩種途徑覆蓋(即實現(xiàn)和覆蓋)。

    補足2:父類的非抽象方法可以被覆蓋為抽象方法[2]。

    [2]子類必須為抽象類。

    package com.ibm.dietime1943.test;

    public class Computer {

    public Computer send() { return new Computer();}
    }

    abstract class Lenovo extends Computer {

    @Override
    public abstract Computer send();
    }

    以上規(guī)則更加詳細的說明請參看另一篇博文: <<JAVA中 @Override 的作用>>

    // 2016/11/21 20:27 bluetata 追記標注補足1(上接博文后追記)

    舉例(來源于OCJP題庫):

    Given:

  • public class Blip {
  • protected int blipvert(int x) { return 0; }
  • }
  • class Vert extends Blip {
  • // insert code here
  • }
    Which five methods, inserted independently at line 5, will compile? (Choose five.)
    A. public int blipvert(int x) { return 0; }
    B. private int blipvert(int x) { return 0; }
    C. private int blipvert(long x) { return 0; }
    D. protected long blipvert(int x) { return 0; }
    E. protected int blipvert(long x) { return 0; }
    F. protected long blipvert(long x) { return 0; }
    G. protected long blipvert(int x, int y) { return 0; }
    Answer: A,C,E,F,G
    Explanation:繼承關(guān)系后,子類重寫父類的方法時,修飾符作用域不能小于父類被重寫方法,所以A正確,B不正確。選項CEFG均不滿足重寫規(guī)則,不是重寫方法(在子類的普通方法)。選項D即為不滿足C-1補足。
  • 里氏替換原則

    這項原則最早是在1987年、由麻省理工學院的由芭芭拉·利斯科夫(Barbara Liskov)在一次會議上名為“數(shù)據(jù)的抽象與層次”的演說中首先提出。里氏替換原則的內(nèi)容可以描述為: “派生類(子類)對象能夠替換其基類(超類)對象被使用。” 以上內(nèi)容并非利斯科夫的原文,而是譯自羅伯特·馬丁(Robert Martin)對原文的解讀。其原文為:Let q(x) be a property provable about objectsx of type T. Thenq(y) should be true for objectsy of typeS where S is a subtype ofT.嚴格的定義:如果對每一個類型為T1的對象o1、都有類型為T2的對象o2、使得以T1定義的所有程序P在所有的對象o1都換成o2時、程序P的行為沒有變化、那么類型T2是類型T1的子類型。通俗的定義:所有引用基類的地方必須能透明地使用其子類的對象。更通俗的定義:子類可以擴展父類的功能,但不能改變父類原有的功能。里氏替換原則包含以下4層含義:1、子類可以實現(xiàn)父類的抽象方法、但是不能[1]覆蓋父類的非抽象方法。(核心)[參照1]

    在我們做系統(tǒng)設(shè)計時、經(jīng)常會設(shè)計接口或抽象類、然后由子類來實現(xiàn)抽象方法、這里使用的其實就是里氏替換原則。子類可以實現(xiàn)父類的抽象方法很好理解、事實上子類也必須完全實現(xiàn)父類的抽象方法、哪怕寫一個空方法、否則會編譯報錯。

    里氏替換原則的關(guān)鍵點在于不能覆蓋父類的非抽象方法。父類中凡是已經(jīng)實現(xiàn)好的方法、實際上是在設(shè)定一系列的規(guī)范和契約、雖然它不強制要求所有的子類必須遵從這些規(guī)范、但是如果子類對這些非抽象方法任意修改、就會對整個繼承體系造成破壞。而里氏替換原則就是表達了這一層含義。

    [1]處的說明:該處的不建議原則、并不是硬性規(guī)定無法不能的含義。增加新功能時、盡量添加新方法實現(xiàn)、而不是(不建議)去重寫父類的方法、也不建議重載父類的方法。// 2016/11/22 15:33 bluetata 追記

    2、子類中可以增加自己特有的方法。3、當子類重寫或?qū)崿F(xiàn)父類的方法時,方法的前置條件(即方法的形參)要比父類方法的輸入?yún)?shù)更寬松。4、當子類的方法重寫或?qū)崿F(xiàn)父類的方法時,方法的后置條件(即方法的返回值)要比父類更嚴格。[參照2]// 2016/11/22 18:54 bluetata 追記 add Start - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -追記來源/Michael727(簡書作者)。原文鏈接:http://www.jianshu.com/p/2aa66a36af26里氏替換原則的核心是抽象,抽象又依賴于繼承這個特性,在OOP當中,繼承的優(yōu)缺點都相當?shù)拿黠@。

    繼承的優(yōu)點:

    ①、代碼重用,減少創(chuàng)建的成本,每個子類擁有父類的方法和屬性。②、子類和父類基本相似,但又與父類有所區(qū)別。③、提高代碼的可擴展性,實現(xiàn)父類的方法就可以了,很多開源框架的擴展接口都是通過繼承父類完成的。④、提高產(chǎn)品或項目的開放性。

    繼承的缺點:。

    ①、繼承是侵入性的,只要繼承就必須擁有父類的所有屬性和方法。②、可能造成子類代碼冗余、靈活性降低,因為子類必須擁有父類的屬性和方法。③、增強了耦合性。當父類的常量、變量和方法被修改時,必須考慮子類的修改,而且在缺乏規(guī)范的環(huán)境下,這種修好可能帶來非常

    糟糕的結(jié)果:大片的代碼需要重構(gòu)。

    總結(jié)

    以上是生活随笔為你收集整理的方法重写(Java篇)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 欧美a v在线播放 | 亚洲AV不卡无码一区二区三区 | www.好吊色 | 国产精品宾馆在线精品酒店 | 午夜福利电影 | 在线视频 日韩 | 国产美女又黄又爽又色视频免费 | 欧美精品自拍视频 | 国产亚洲色婷婷久久 | 999伊人 | 亚洲av无码国产精品久久久久 | 亚洲高清免费观看 | 三级爱爱 | 18禁裸男晨勃露j毛免费观看 | 爱爱视频在线免费观看 | 亚洲久久视频 | 妖精视频一区二区三区 | 中文字幕在线2021 | 九九视频免费观看 | 亚洲精品乱码久久 | 国产浮力影院 | 日本不卡一区二区三区在线观看 | 亚洲av成人精品日韩在线播放 | 久草欧美视频 | 麻豆国产一区二区三区 | 夜色导航 | 国产亚洲一区二区三区四区 | 国产污视频在线 | 亚洲精品www久久久 一级aaa毛片 | 丁香久久综合 | xxxwww在线观看 | 麻豆欧美 | 日日弄天天弄美女bbbb | 天天碰天天摸 | 九一精品一区 | 成人h动漫精品一区二区 | 亚洲AV无码精品色毛片浪潮 | 男生插女生的网站 | 中国大陆高清aⅴ毛片 | 欧美亚洲 | 青青草官网 | 老熟女毛茸茸浓毛 | 国产九九在线 | 久久精品播放 | 2019亚洲男人天堂 | 日本中文字幕一区 | 韩国黄色av | 男女做爰猛烈高潮描写 | 欧美xxxx免费虐 | 怡红院av在线| 欧美黄色免费网站 | 亚洲天天综合 | 国产精品美女在线 | 成人黄色片视频 | 成人av免费在线 | 日韩一及片| 久久观看最新视频 | 日本免费在线观看 | 国产欧美日韩二区 | 国产夫妻在线 | 四虎最新站名点击进入 | 捆绑无遮挡打光屁股 | 国产在线视频导航 | 日本久久黄色 | 成人黄色短视频在线观看 | 大j8黑人w巨大888a片 | www.国产免费 | 91视频h | 国产猛男猛女超爽免费视频 | 韩国裸体网站 | 水蜜桃亚洲精品 | 黄色一级a毛片 | 我要操av | 欧美午夜视频在线观看 | www.国产视频.com | 在线香蕉视频 | av手机版| 欧美视频网站 | 国产熟女精品视频 | 无码人妻丰满熟妇啪啪欧美 | 亚洲第一女人av | 成人av在线资源 | 好看的黄色录像 | 91 久久| 误杀1电影免费观看高清完整版 | 91精品国产aⅴ一区二区 | 黄色精品一区二区 | 女同av在线播放 | 久久久99精品免费观看 | 少妇三级 | 91插插视频 | 日本女人黄色片 | 第一福利在线视频 | 欧美高清视频一区二区 | 超碰资源在线 | 日韩黄色网络 | 性欧美成人播放77777 | 久久久久久久女国产乱让韩 | 粉嫩av国产一区二区三区 |