重载和重写除了在名称上有些相似之外,其实是完全不同的两个东西。
重载的目的是使得我们能够用用一个统一的接口名称来调用一系列方法。这些方法的目的也许是一样的,但是它们的实现方式会根据传入的参数不同而不同。
重写涉及到继承这个概念中的问题。子类继承了父类的方法,但是它可能需要有不同的操作行为,这时候就需要在子类中重写这个父类方法。
重载本身并不是多态,同时运行时绑定重载方法也不是多态的表现。它们以及一些其他的东西都是其面向对象多态性的使用(原文:All these and more are used to exercise the object oriented property polymorphism.总感觉翻译不要,故贴上来)。
让我们来详细讨论下重载。在各种网站上我看到了大量的重载的例子。它们向类中添加更多的属性、方法,把它变得看起来更庞大作为重载的象征。事实上正确的方式是,当我们使用重载时外部看起来我们的类会变得更加紧凑。
这里贴出来两个图片,第一张里面是印度的古典乐器脚踏式风琴,它是现代钢琴的鼻祖。另一幅图片是现代的电子琴。在我们的重载语境中,古典风琴是重载之前,电子琴是重载之后。
1
2
3
4
5
6
7
8
9
10
11
|
public class OverloadingExample { public static void main(String args[]){ System.out.println(playMusic( "C sharp" , "D sharp" )); System.out.println(playMusic( "C" , "D flat" , "E flat" )); } public static String playMusic(String c, String d){ return c+d; } public static String playMusic(String c, String d, String e){ return c+d+e; } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
package com.javapapaer.java; public class NullArguementOverloading { public static void main(String[] args) { NullArguementOverloading obj = new NullArguementOverloading(); obj.overLoad( null ); } private void overLoad(Object o){ System.out.println( "Object o arguement method." ); } private void overLoad( double [] dArray){ System.out.println( "Double array argument method." ); } } |
当继承一个类的时候,根据父类方法的访问修饰符子类可以获得所有protect以上的父类方法。但是父类的方法的具体行为可能在子类中并不适合,因此我们需要根据子类对于这个方法的需求重写继承自父类的这个方法。重写后原来的旧方法对于这个子类会完全废弃。
看看下面这个猛兽皮卡,因为需求不同了,原来又小又旧的轮子被换成了巨无霸。这就是现实生活中的重写。
在Java中默认所有对象都是继承自Object类。Object有个叫equals的方法,在String类中重写了它的默认行为。String中通过比较传入的对象与本身保存的字符串序列一一对比看是否相等。
关于上面Overloading Puzzle,以免强迫症患者费心敲代码在此给出答案和解释。
程序输出:Double array argument method.
原因是Java对于重载的处理有个最精确原则。Object和double[]都可以和null匹配,但是两者对比而言,double[]比 Object匹配得更精确,所以调用了下面的overLoad方法。如果想让程序调用Object的overLoad方法则需要一个强制类型转换obj.overLoad((Object)null);
这样Object的overLoad就要比double[]的更精确,会输出Object o arguement method.。
下面这段代码也许理解起来会更清晰一些,ArrayList继承自List:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import java.util.ArrayList; import java.util.List; public class OverridePuzzle { private void overloadList(List list){ System.out.println( "List arguement method." ); } private void overloadList(ArrayList arrayList){ System.out.println( "ArrayList arguement method" ); } public static void main(String[] args) { OverridePuzzle op = new OverridePuzzle(); op.overloadList( null ); } } |
那又要问了,如果上文的NullArguementOverloading代码中还有个overLoad方法如下:
1
2
3
|
private void overLoad(String str) { System.out.println( "String argument method." ); } |
obj.overLoad(null)
那一行会编译报错。String的 overLoad和double[]的overLoad都可以匹配,但是两者在继承属上是平行的,因此编译器也不知道到底该调用哪一个重载方法。另外这段 代码还说明了一个问题:重载是在编译期就已经确定了的,并不需要等到运行时才能确定。这也是为什么说它不是多态的一个原因。还有下面一段代码作为佐证:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
import java.util.ArrayList; import java.util.List; public class OverridePuzzle { private void overloadList(List list){ System.out.println( "List arguement method." ); } private void overloadList(ArrayList arrayList){ System.out.println( "ArrayList arguement method" ); } public static void main( String [] args) { OverridePuzzle op = new OverridePuzzle(); List list = new ArrayList< String >(); op.overloadList(list); } } |
深入理解重载和重写及与之相关的多态性 Overloading and Overriding(转)
原文:http://www.cnblogs.com/weink1215/p/4951731.html