java的Override與Overload的區別---看這就夠了
阿新 • • 發佈:2020-07-21
Java 重寫(Override)與過載(Overload)
重寫或覆寫都是指Override,而Overload是過載;----javaSE5開始就出現這樣的註解;
但是我們很模糊的區分請他們的區別,甚至有的時候不知道去選擇那一個去用。
那我借《Thinking in Java》上的例子來解釋一下:
//: CADSystem.java package com.wuroc.chapterseven; import static com.wuroc.util.Print.*; /** * @author WuRoc * @GitHub www.github.com/WuRoc * @version1.0 * @2020年7月20日 * * */ class Shape { Shape(int i) { print("Shape constructor"); } void dispose() { print("Shap dispose"); } } class Circle extends Shape{ Circle(int i){ super(i); print("Deawing Circle"); } void dispose() { print("Erasing Circle"); } } class Triangle extends Shape{ Triangle(int i){ super(i); print("Drawing Circle"); } void dispose() { print("Erasing Triangle"); super.dispose(); } } class Line extends Shape{ private int start, end; /** * @param i*/ Line(int start, int end) { super(start); this.start = start; this.end = end; print("Drawing Line: " + start + ", " + end); } void dispose() { print("Erasing Line: " + start + ", " + end); super.dispose(); } } public class CADSystem extends Shape { private Circle c; private Triangle t; //這裡只是一個物件的初始化 private Line lines[] = new Line[3]; /** * @param i */ public CADSystem(int i) { super(i + 1); for(int j = 0; j < lines.length; j++) lines[j] = new Line(j, j*j); c = new Circle(1); t = new Triangle(1); print("Combined constructor"); } public void dispose() { print("CADSystem.dispose()"); //清理的順序與建立時相反 t.dispose(); c.dispose(); for(int i = lines.length - 1; i >= 0; i--) lines[i].dispose(); super.dispose(); } public static void main(String[] args) { CADSystem x = new CADSystem(47); try { }finally { x.dispose(); } } }
同學們可以看下這裡面是用的哪一種呢?
答案是Override ,為什麼呢?
這裡面每個類都覆寫Shape的dispose()方法,並運用super來呼叫該方法的基類版本;也就是說繼承的情況的下,會出現重寫這個功能,;
但是我們為什麼要去重寫呢?
大概是想減輕程式設計師的重複,既可以新類的功能加以修改,又能讓別人很清楚我們的程式碼做了什麼。
並且但出現absolate類時,我們只能通過重寫,來實現一些功能;
那我們來看一下過載。過載還是比較容易的,因為它是多變的。
但是我們也要注意,因為太多的過載會讓你眼花繚亂。
//: Hide.java package com.wuroc.chapterseven; /** * @author WuRoc * @GitHub www.github.com/WuRoc * @version 1.0 * @2020年7月21日 * * */ class Homer{ char doh(char c) { System.out.println("doh(char)"); return 'd'; } float doh(float f) { System.out.println("doh(float)"); return 1.0f; } } class Milhouse{} class Bart extends Homer { void doh(Milhouse m) { System.out.println("doh(Milhouse)"); } } public class Hide{ public static void main(String[] args) { Bart b = new Bart(); b.doh(1); b.doh('x'); b.doh(1.0f); System.out.println(b.doh(1.0f)); b.doh(new Milhouse()); } } /*Output: doh(float) doh(char) doh(float) doh(float) 1.0 doh(Milhouse) *///
可以看出java的基類擁有某個已被多次過載的方法名稱,那麼在派生類(子類或匯出類)中重新定義該方法名稱並不會遮蔽其在基類中任何版本(這一點與C++不同,
C++中需要遮蔽基類的方法)。
可以從這兩個例子看出,過載與重寫相同的就是方法名不變,其他的就各有各的特點。
如果不知道自己重寫的方法寫對了嗎?
可以加@Override註解可以防止你在不想過載時而意外地進行了過載。
參考:《Thinking in Java》---Bruce Eckel