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

Java 重寫時應(yīng)當遵守的 11 條規(guī)則

 更新時間:2021年03月29日 10:20:39   作者:沉默王二  
這篇文章主要介紹了Java 重寫時應(yīng)當遵守的 11 條規(guī)則,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

CSDN 的小伙伴們,大家好,我是沉默王二。

重寫(Overriding)算是 Java 中一個非常重要的概念,理解重寫到底是什么對每個 Java 程序員來說都至關(guān)重要,這篇文章就來給大家說說重寫過程中應(yīng)當遵守的 12 條規(guī)則。

01、什么是重寫?

重寫帶來了一種非常重要的能力,可以讓子類重新實現(xiàn)從超類那繼承過來的方法。在下面這幅圖中,Animal 是父類,Dog 是子類,Dog 重新實現(xiàn)了 move() 方法用來和父類進行區(qū)分,畢竟狗狗跑起來還是比較有特色的。

重寫的方法和被重寫的方法,不僅方法名相同,參數(shù)也相同,只不過,方法體有所不同。

02、哪些方法可以被重寫?

規(guī)則一:只能重寫繼承過來的方法。

因為重寫是在子類重新實現(xiàn)從父類繼承過來的方法時發(fā)生的,所以只能重寫繼承過來的方法,這很好理解。這就意味著,只能重寫那些被 public、protected 或者 default 修飾的方法,private 修飾的方法無法被重寫。

Animal 類有 move()、eat()sleep() 三個方法:

public class Animal {
 public void move() { }

 protected void eat() { }
 
 void sleep(){ }
}

Dog 類來重寫這三個方法:

public class Dog extends Animal {
 public void move() { }

 protected void eat() { }

 void sleep(){ }
}

OK,完全沒有問題。但如果父類中的方法是 private 的,就行不通了。

public class Animal {
 private void move() { }
}

此時,Dog 類中的 move() 方法就不再是一個重寫方法了,因為父類的 move() 方法是 private 的,對子類并不可見。

public class Dog extends Animal {
 public void move() { }
}

03、哪些方法不能被重寫?

規(guī)則二:final、static 的方法不能被重寫。

一個方法是 final 的就意味著它無法被子類繼承到,所以就沒辦法重寫。

public class Animal {
 final void move() { }
}

由于父類 Animal 中的 move() 是 final 的,所以子類在嘗試重寫該方法的時候就出現(xiàn)編譯錯誤了!

同樣的,如果一個方法是 static 的,也不允許重寫,因為靜態(tài)方法可用于父類以及子類的所有實例。

public class Animal {
 final void move() { }
}

重寫的目的在于根據(jù)對象的類型不同而表現(xiàn)出多態(tài),而靜態(tài)方法不需要創(chuàng)建對象就可以使用。沒有了對象,重寫所需要的“對象的類型”也就沒有存在的意義了。

04、重寫方法的要求

規(guī)則三:重寫的方法必須有相同的參數(shù)列表。

public class Animal {
 void eat(String food) { }
}

Dog 類中的 eat() 方法保持了父類方法 eat() 的同一個調(diào)調(diào),都有一個參數(shù)——String 類型的 food。

public class Dog extends Animal {
 public void eat(String food) { }
}

一旦子類沒有按照這個規(guī)則來,比如說增加了一個參數(shù):

public class Dog extends Animal {
 public void eat(String food, int amount) { }
}

這就不再是重寫的范疇了,當然也不是重載的范疇,因為重載考慮的是同一個類。

規(guī)則四:重寫的方法必須返回相同的類型。

父類沒有返回類型:

public class Animal {
 void eat(String food) { }
}

子類嘗試返回 String:

public class Dog extends Animal {
 public String eat(String food) {
  return null;
 }
}

于是就編譯出錯了(返回類型不兼容)。

規(guī)則五:重寫的方法不能使用限制等級更嚴格的權(quán)限修飾符。

可以這樣來理解:

  • 如果被重寫的方法是 default,那么重寫的方法可以是 default、protected 或者 public。
  • 如果被重寫的方法是 protected,那么重寫的方法只能是 protected 或者 public。
  • 如果被重寫的方法是 public, 那么重寫的方法就只能是 public。

舉個例子,父類中的方法是 protected:

public class Animal {
 protected void eat() { }
}

子類中的方法可以是 public:

public class Dog extends Animal {
 public void eat() { }
}

如果子類中的方法用了更嚴格的權(quán)限修飾符,編譯器就報錯了。

規(guī)則六:重寫后的方法不能拋出比父類中更高級別的異常。

舉例來說,如果父類中的方法拋出的是 IOException,那么子類中重寫的方法不能拋出 Exception,可以是 IOException 的子類或者不拋出任何異常。這條規(guī)則只適用于可檢查的異常。

可檢查(checked)異常必須在源代碼中顯式地進行捕獲處理,不檢查(unchecked)異常就是所謂的運行時異常,比如說 NullPointerException、ArrayIndexOutOfBoundsException 之類的,不會在編譯器強制要求。

父類拋出 IOException:

public class Animal {
 protected void eat() throws IOException { }
}

子類拋出 FileNotFoundException 是可以滿足重寫的規(guī)則的,因為 FileNotFoundException 是 IOException 的子類。

public class Dog extends Animal {
 public void eat() throws FileNotFoundException { }
}

如果子類拋出了一個新的異常,并且是一個 checked 異常:

public class Dog extends Animal {
 public void eat() throws FileNotFoundException, InterruptedException { }
}

那編譯器就會提示錯誤:

Error:(9, 16) java: com.itwanger.overriding.Dog中的eat()無法覆蓋com.itwanger.overriding.Animal中的eat()
被覆蓋的方法未拋出java.lang.InterruptedException

但如果子類拋出的是一個 unchecked 異常,那就沒有沖突:

public class Dog extends Animal {
 public void eat() throws FileNotFoundException, IllegalArgumentException { }
}

如果子類拋出的是一個更高級別的異常:

public class Dog extends Animal {
 public void eat() throws Exception { }
}

編譯器同樣會提示錯誤,因為 Exception 是 IOException 的父類。

Error:(9, 16) java: com.itwanger.overriding.Dog中的eat()無法覆蓋com.itwanger.overriding.Animal中的eat()
被覆蓋的方法未拋出java.lang.Exception

05、如何調(diào)用被重寫的方法?

規(guī)則七:可以在子類中通過 super 關(guān)鍵字來調(diào)用父類中被重寫的方法。

子類繼承父類的方法而不是重新實現(xiàn)是很常見的一種做法,在這種情況下,可以按照下面的形式調(diào)用父類的方法:

super.overriddenMethodName();

來看例子。

public class Animal {
 protected void eat() { }
}

子類重寫了 eat() 方法,然后在子類的 eat() 方法中,可以在方法體的第一行通過 super.eat() 調(diào)用父類的方法,然后再增加屬于自己的代碼。

public class Dog extends Animal {
 public void eat() {
  super.eat();
  // Dog-eat
 }
}

06、重寫和構(gòu)造方法

規(guī)則八:構(gòu)造方法不能被重寫。

因為構(gòu)造方法很特殊,而且子類的構(gòu)造方法不能和父類的構(gòu)造方法同名(類名不同),所以構(gòu)造方法和重寫之間沒有任何關(guān)系。

07、重寫和抽象方法

規(guī)則九:如果一個類繼承了抽象類,抽象類中的抽象方法必須在子類中被重寫。

先來看這樣一個接口類:

public interface Animal {
 void move();
}

接口中的方法默認都是抽象方法,通過反編譯是可以看得到的:

public interface Animal
{
 public abstract void move();
}

如果一個抽象類實現(xiàn)了 Animal 接口,move() 方法不是必須被重寫的:

public abstract class AbstractDog implements Animal {
 protected abstract void bark();
}

但如果一個類繼承了抽象類 AbstractDog,那么 Animal 接口中的 move() 方法和抽象類 AbstractDog 中的抽象方法 bark() 都必須被重寫:

public class BullDog extends AbstractDog {
 
 public void move() {}
 
 protected void bark() {}
}

08、重寫和 synchronized 方法

規(guī)則十:synchronized 關(guān)鍵字對重寫規(guī)則沒有任何影響。

synchronized 關(guān)鍵字用于在多線程環(huán)境中獲取和釋放監(jiān)聽對象,因此它對重寫規(guī)則沒有任何影響,這就意味著 synchronized 方法可以去重寫一個非同步方法。

09、重寫和 strictfp 方法

規(guī)則十一:strictfp 關(guān)鍵字對重寫規(guī)則沒有任何影響。

如果你想讓浮點運算更加精確,而且不會因為硬件平臺的不同導(dǎo)致執(zhí)行的結(jié)果不一致的話,可以在方法上添加 strictfp 關(guān)鍵字。因此 strictfp 關(guān)鍵和重寫規(guī)則無關(guān)。

到此這篇關(guān)于Java 重寫時應(yīng)當遵守的 11 條規(guī)則的文章就介紹到這了,更多相關(guān)Java 重寫規(guī)則內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java深入分析了解平衡二叉樹

    Java深入分析了解平衡二叉樹

    平衡二叉樹又被稱為AVL樹(有別于AVL算法),且具有以下性質(zhì):它是一棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,并且左右兩個子樹都是一棵平衡二叉樹。本文將詳解介紹一下平衡二叉樹的原理與實現(xiàn),需要的可以參考一下
    2022-06-06
  • 一文帶你掌握Java?SPI的原理和實踐

    一文帶你掌握Java?SPI的原理和實踐

    在Java中,我們經(jīng)常會提到面向接口編程,這樣減少了模塊之間的耦合,更加靈活,Java?SPI?(Service?Provider?Interface)就提供了這樣的機制,本文就來講講它的原理與具體使用吧
    2023-05-05
  • 基于slf4j日志MDC輸出格式的問題

    基于slf4j日志MDC輸出格式的問題

    這篇文章主要介紹了基于slf4j日志MDC輸出格式的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • 淺談Java中static關(guān)鍵字的作用

    淺談Java中static關(guān)鍵字的作用

    這篇文章主要介紹了Java中static關(guān)鍵字的作用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • java實現(xiàn)web實時消息推送的七種方案

    java實現(xiàn)web實時消息推送的七種方案

    這篇文章主要為大家介紹了java實現(xiàn)web實時消息推送的七種方案示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • Spring Boot JPA Repository之existsBy查詢方法失效的解決

    Spring Boot JPA Repository之existsBy查詢方法失效的解決

    這篇文章主要介紹了Spring Boot JPA Repository之existsBy查詢方法失效的解決方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • 使用@Validated注解進行校驗卻沒有效果的解決

    使用@Validated注解進行校驗卻沒有效果的解決

    這篇文章主要介紹了使用@Validated注解進行校驗卻沒有效果的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • 淺談Java中的hashcode方法(推薦)

    淺談Java中的hashcode方法(推薦)

    本篇文章主要介紹了Java中的hashcode方法,詳細的介紹了hashCode方法的作用,具有一定的參考價值,有需要的可以了解一下。
    2016-12-12
  • eclipse實現(xiàn)ECDSA數(shù)字簽名

    eclipse實現(xiàn)ECDSA數(shù)字簽名

    這篇文章主要為大家詳細介紹了eclipse實現(xiàn)ECDSA數(shù)字簽名,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • 簡單了解SpringCloud運行原理

    簡單了解SpringCloud運行原理

    這篇文章主要介紹了簡單了解SpringCloud運行原理,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-11-11

最新評論