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 * @version 1.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