为啥java中需要方法重载和覆盖? [复制]
Posted
技术标签:
【中文标题】为啥java中需要方法重载和覆盖? [复制]【英文标题】:Why is method overloading and overriding needed in java? [duplicate]为什么java中需要方法重载和覆盖? [复制] 【发布时间】:2012-12-23 02:31:00 【问题描述】:可能重复:Polymorphism vs Overriding vs Overloading
我很想知道为什么在 java 中需要方法重载和覆盖?
我已经阅读了一些关于此的文章,但无法理解为什么实际需要它?
我还在***中访问了以下网址,但我还不清楚这个主题。
Java overloading and overriding
任何实际示例将不胜感激。
提前致谢。
【问题讨论】:
en.wikipedia.org/wiki/Function_overloading en.wikipedia.org/wiki/Method_overriding 都有实例。 从你引用的链接中有什么不明白的地方? @fge:我可以理解两者之间的区别,但我不清楚何时以及如何选择这种多态类型。 您可以选择在使用继承时覆盖方法。当您想使用具有不同类型参数的相同方法名称时,您可以选择重载方法。真的没有在两者之间进行选择的概念......它们完全不同。 @jahroy:感谢您的 cmets。但是仍然有像我这样的人对了解我们不知道的事情感兴趣。如果可以的话,请帮助我。 【参考方案1】:来自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)
是不同且独特的方法,因为它们需要不同的参数类型。
您不能声明多个具有相同名称、相同数量和类型的参数的方法,因为编译器无法区分它们。
编译器在区分方法时不考虑返回类型,因此即使返回类型不同,也不能声明两个签名相同的方法。
方法覆盖,在面向对象的编程中,是一种语言特性,它允许子类或子类提供已由其超类或父类之一提供的方法的特定实现。子类中的实现通过提供与父类中的方法具有相同名称、相同参数或签名以及相同返回类型的方法来覆盖(替换)超类中的实现。执行的方法的版本将由用于调用它的对象确定。如果使用父类的对象调用方法,则执行父类中的版本,如果使用子类的对象调用方法,则执行子类中的版本。
【讨论】:
感谢您的宝贵回答。【参考方案2】:覆盖
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)
...这比重载的解决方案非常丑陋且难以阅读。
【讨论】:
感谢分享。【参考方案3】:答案主要围绕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!");
这不是赌注示例,但假设这是为了允许用户从公式中设置 a
、b
和 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!
,因为用户已经创建了自己的公式。这有几个主要原因:
-
如果一个函数是从超类继承的,通常子类会想要覆盖该函数。但是,超类可能具有其类的默认代码。因此,如果用户希望使用自己的代码,则必须重写此函数。
通常,超类希望使用默认代码确保某个函数返回时不会出错。在其他情况下,默认代码也很有帮助。因此,这提供了另一种选择:如果用户不需要默认代码,他们可以覆盖它。
【讨论】:
以上是关于为啥java中需要方法重载和覆盖? [复制]的主要内容,如果未能解决你的问题,请参考以下文章