2012-04-20 59 views
101

當我製作屬於我自己的Android自定義類時,我的原生類是extend。然後,當我要重寫基方法,我總是叫super()方法,就像我一直做onCreateonStop當重寫時不調用super()方法?

而且我認爲這是它,因爲從一開始Android團隊建議我們始終每個方法覆蓋請致電super

但是,在很多書我可以看到,開發商,比我更有經驗,往往忽略調用super,我真懷疑他們做它作爲一個知識的缺乏。例如,看一下這個基本SAX分析器類,其中superstartElementcharactersendElement省略:

public class SAXParser extends DefaultHandler{ 
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { 
     if(qName.equalsIgnoreCase("XXY")) { 
      //do something 
     } 
    } 

    public void characters(char[] ch, int start, int length) throws SAXException { 
     //do something 
    } 

    public void endElement(String uri, String localName, String qName) throws SAXException { 
     if(qName.equalsIgnoreCase("XXY")) { 
      //do something 
     }else() { 
      //do something 
     } 
    } 
} 

如果您嘗試創建通過Eclipse或任何其他IDE任何覆蓋方法,super總是被創建爲自動化過程的一部分。

這只是一個簡單的例子。書籍是,全部類似代碼

他們如何知道您何時必須致電super以及何時可以省略呼叫?

PS。不要拘泥於這個特定的例子。這只是從很多例子中隨機挑選的一個例子。

(這聽起來像一個初學者的問題,但我真的很困惑。)

+3

endElement的API文檔中提到「默認情況下,不做任何事情,應用程序編寫者可以重寫此方法...」,這意味着您可以安全地調用super,因爲它「沒有」,但您不必你真的可以覆蓋它。如果您閱讀該方法的文檔,您可以經常分辨是否必須/可以/不應該這樣做。 – zapl 2012-04-20 11:07:57

+1

小例子:我在啓動畫面中使用onBackPressed(),並且我不會調用超級,所以它不會熄滅,它只是禁用按鈕。 – 2012-04-25 03:10:36

+0

@sandalone對不起,在這裏提問,但是您是否有任何關於如何通過應用內結算處理增值稅的經驗,以及哪些國家/地區是由Google自動完成的,哪些國家/地區需要手動上報/繳納增值稅稅?請參閱http://stackoverflow.com/questions/36506835/android-in-app-billing-vat-tax – 2016-04-08 18:51:37

回答

130

通過調用super方法,你不覆蓋方法的行爲,你延長它。

super的調用將執行您正在擴展的類爲該方法定義的任何邏輯。考慮到在您的方法覆蓋中調用super的實現時可能很重要。例如:

public class A { 
    public void save() { 
     // Perform save logic 
    } 
} 

public class B extends A { 
    private Object b; 
    @Override 
    public void save() { 
     super.save(); // Performs the save logic for A 
     save(b); // Perform additional save logic 
    } 
} 

B.save()的呼叫將執行save()邏輯兩者AB,在這個特定的順序。如果您在B.save()之內沒有撥打super.save(),則不會調用A.save()。如果您在save(b)之後撥打super.save(),A.save()之後會有效執行B.save()

如果你想覆蓋super的行爲(即,完全忽視它的實施,並提供一切你自己),你不應該叫super

在您提供的SAXParser示例中,implementationsDefaultHandler這些方法只是空的,以便子類可以覆蓋它們併爲這些方法提供行爲。在這個方法的javadoc這也是指出。

public void startElement (String uri, String localName, 
    String qName, Attributes attributes) throws SAXException { 
    // no op 
} 

關於通過集成開發環境生成代碼的super()默認電話,在他的批評是@barsju指出的那樣,在每個構造有以super()(即使你沒有在你的代碼寫),隱式調用它在這種情況下,意味着撥打super的默認構造函數。 IDE只是爲你寫下來的,但如果你刪除它也會被調用。另外注意,在實現構造函數時,super()或其任何帶參數的變體(即super(x,y,z))只能在該方法的開頭處調用

+14

也沒有注意到,對於構造函數'super()'(超類的默認構造函數)總是被調用,甚至如果你沒有指定它。如果超類沒有默認的構造函數,如果您沒有顯式調用超類的構造函數之一作爲子類構造函數中的第一條語句,將會得到編譯錯誤。 – barsju 2012-04-20 10:55:59

+1

是的,它基本上只是懶惰 - 我們知道的方法不做任何事情只是爲了簡潔省略 – Voo 2012-04-20 10:59:33

+1

感謝您的寶貴意見,@ barjsu,我已經在答案中包含了這些細節。 – 2012-04-20 11:09:26

3

哈維給了一個更好的答案..但你也許可能會知道是什麼super()做一個重寫的方法......它的廣告你有什麼用默認的行爲做..

如調用時:

onDraw() 

在重寫時,視圖類方法..你說super.onDraw(前畫的東西),它出現一次的觀點是完全畫..所以在這裏呼籲super是必要的,因爲Android有一些非常重要的事情做(像onCreate())

,但在同一時間

onLongClick() 

當你重寫這個你不想叫超,因爲它帶來了一個對話框,爲一個EditText上或任何其他類似的視圖選項列表..多數民衆贊成基本差異..你可以選擇離開一段時間..但對於其他方法,如onCreate() , onStop(),你應該讓操作系統處理它..

2

我沒有清楚地問你的問題,但如果你問爲什麼不撥打super方法:

調用super方法是有原因的:如果在父類中沒有零參數構造函數,那麼就不可能爲它創建子類,所以要麼在父類中保留一個無參數構造函數,要麼您需要在子類構造函數的頂部定義super()調用語句argument(how much argument constructor you have used in super class)

我希望這會有所幫助。如果沒有,請告訴我。

7

,你應該在你的頭做的測試是:

「難道我想這一切方法爲我做的功能,然後做一些事情之後?」如果是,那麼你想打電話給super(),然後完成你的方法。對於諸如onDraw()等「重要」方法來說,這是很正確的,後者在後臺處理很多事情。

如果您只想要一些功能(與大多數方法一樣,您將覆蓋),那麼您可能不想撥打super()

15

他們怎麼知道你什麼時候必須打電話超時,什麼時候可以省略打電話?

通常,如果一個特殊的API方法對底層框架上下文生命週期有重要意義,它總是會在API文檔中明確陳述和突出顯示,如Activity.onCreate() API documentation。此外,如果API遵循健壯的設計,它應該在項目編譯時拋出一些異常來提醒消費者開發人員,並確保它在運行時不會產生錯誤。

如果在API文檔中沒有明確說明這一點,那麼消費者開發人員認爲在覆蓋它時不強制調用API方法是非常安全的。由消費者開發人員決定是否使用默認行爲(調用super方法)或完全覆蓋它。

如果條件允許(我喜歡開源軟件),消費開發人員可以隨時查看API源代碼並查看該方法實際上是如何編寫的。例如,請查看Activity.onCreate() sourceDefaultHandler.startElement() source

+0

感謝您向我解釋其他內容。感謝您提醒我檢查源代碼。 – sandalone 2012-04-21 15:17:57

2

我實現像

public class ConstraintArrayList<T> extends ArrayList<T> { 
    ConstraintArrayList(Constraint<T> cons) {this.cons = cons;} 
    @Override 
    public boolean add(T element) { 
    if (cons.accept(element)) 
     return super.add(element); 
    return false; 
    } 
} 

約束數組列表如果你看一下代碼,它根本實際上是讓超類之前的一些預檢執行實際添加元素到列表中。 這告訴的兩倍原因方法重載之一:要擴展什麼超階級可以做

  • 特異性您希望通過多態性添加特定的行爲,如在普通動物

    1. 擴展王移動語義學的例子,鳥類移動(飛)和青蛙移動(跳)的方式是特定於每個子類的。
  • 相關問題