2013-01-09 92 views
15

可能重複:
Polymorphism vs Overriding vs Overloading爲什麼在java中需要重載和覆蓋方法?

我掙扎知道爲什麼方法重載和壓倒一切的需要在Java

我已閱讀了一些關於此的文章,但無法理解爲什麼實際上需要它?

我也訪問了下面的url在stackoverflow但我不清楚這個話題呢。

Java overloading and overriding

任何實際的例子可以理解。

在此先感謝。

+1

http://en.wikipedia.org/wiki/Function_overloading http://en.wikipedia.org/wiki/Method_overriding 都有實際的例子。 –

+0

你從你引用的鏈接中知道些什麼? – fge

+1

@fge:我可以理解兩者之間的區別,但是我不清楚何時以及如何選擇這種多態類型。 –

回答

30

doc
方法重載:假設你有一個類,可以用書法來繪製各種類型的數據(字符串,整數,等等),幷包含用於繪製每個數據類型的方法。對每種方法使用新名稱很麻煩 - 例如,drawString,drawInteger,drawFloat等等。在Java編程語言中,可以對所有繪圖方法使用相同的名稱,但將不同的參數列表傳遞給每個方法。因此,數據繪圖類可能會聲明四個名爲draw的方法,每個方法都有不同的參數列表。

public class DataArtist { 
    ... 
    public void draw(String s) { 
     ... 
    } 
    public void draw(int i) { 
     ... 
    } 
    public void draw(double f) { 
     ... 
    } 
    public void draw(int i, double f) { 
     ... 
    } 
} 

重載方法通過傳遞給方法的參數的數量和類型來區分。在代碼示例中,draw(String s)draw(int i)是不同且唯一的方法,因爲它們需要不同的參數類型。

您不能聲明多個具有相同名稱和相同數量和類型的參數的方法,因爲編譯器無法區分它們。

編譯器在區分方法時不考慮返回類型,所以即使它們具有不同的返回類型,也不能聲明具有相同簽名的兩個方法。

在面向對象編程中,方法重寫是一種語言功能,它允許子類或子類提供已由其超類或父類之一提供的方法的特定實現。子類中的實現通過提供與父類中的方法具有相同名稱,相同參數或簽名以及相同返回類型的方法來覆蓋(替換)超類中的實現。執行的方法的版本將由用於調用它的對象決定。如果父類的對象用於調用方法,則會執行父類中的版本,但如果使用子類的對象調用該方法,則將執行子類中的版本。

+1

感謝您的寶貴答案。 –

+0

歡迎您:) –

2

答案主要集中在使用interface s和abstract class es。

比方說,你有一個代碼塊:

abstract class testAbstract { 
    int a; int b; int c; 
    public String testFunction() { 
     System.out.println("Override me!"); 
     return "default"; 
    } 

    public void setValuesByFormula(double a, double b) { 
     System.out.println("No formula set!"); 
    } 
} 

這不是賭的例子,但我們說這是爲了讓用戶設置ab,並c從公式。用戶想創建的這個新的實例:

class testClass extends testAbstract { 
} 

testClass目前包含什麼都沒有。但它擴展了testAbstract,因此具有功能setValuesByFormula。但是,當用戶嘗試呼叫此消息時,系統輸出消息:No formula set!

用戶此時必須做的是@Override原始功能。因此,新的類變爲:

class testClass extends testInterface { 
    public void setValuesByFormula(double a, double b) { 
     //A not really relevant formula goes here. 
    } 
} 

這將停止消息No formula set!作爲用戶已經創建他們自己的公式。這是需要幾個主要原因:

  1. 如果函數是從超類繼承,往往孩子會想要覆蓋該函數。但是,超類可能具有其類的默認代碼。因此,如果用戶希望使用自己的代碼,則必須覆蓋此功能。
  2. 通常,超類想要使用默認代碼確保某個函數無錯地返回。還有其他情況下默認代碼是有幫助的。因此,這提供了一種替代方案:如果用戶不需要默認代碼,則可以覆蓋它。
13

重寫

Java Docs說:

在具有相同簽名(名稱,加上 數量及其參數的類型)的子類的實例方法和返回類型超類中的實例方法將覆蓋超類的方法。

子類重寫方法的能力允許一個類繼承自其行爲足夠「接近」的超類,然後 根據需要修改行爲。

覆蓋是使用繼承時可用的功能。

當從另一個類擴展的類想要使用父類的大部分功能並希望在某些情況下實現特定功能時使用它。

在這種情況下,我們可以創建具有與父類相同的名稱和簽名的方法。這種方法掩蓋了父方法的新方法,並且默認情況下會被調用。

class Thought { 
    public void message() { 
     System.out.println("I feel like I am diagonally parked in a parallel universe."); 
    } 
} 

public class Advice extends Thought { 
    @Override // @Override annotation in Java 5 is optional but helpful. 
    public void message() { 
     System.out.println("Warning: Dates in calendar are closer than they appear."); 
    } 
} 

Overloading

在Java中重載是創造了多個同名的方法的能力,但具有不同的參數。

這樣做的主要優點是代碼清潔。

我們來看看String.valueOf的方法。這種方法的重載版本被定義爲:

static String valueOf(boolean b) 
static String valueOf(char c) 
static String valueOf(char[] data) 
static String valueOf(char[] data, int offset, int count) 
static String valueOf(double d) 
static String valueOf(float f) 
static String valueOf(int i) 
static String valueOf(long l) 
static String valueOf(Object obj) 

這意味着如果我們具有任何類型的變量,我們可以通過使用String.valueOf(variable)得到它的字符串表示。

如果超載是不允許我們就會有看起來像這樣的方法......

static String valueOfBoolean(boolean b) 
static String valueOfChar(char c) 
static String valueOfCharArray(char[] data) 
static String valueOfCharArrayWithOffset(char[] data, int offset, int count) 
static String valueOfDouble(double d) 
static String valueOfFloat(float f) 
static String valueOfInt(int i) 
static String valueOfLong(long l) 
static String valueOfObject(Object obj) 

...這是非常醜陋的,更難比超載的解決方案閱讀。

+0

感謝分享。 –