为什么需要方法重载?

  在编程语言中,名字的使用很重要。创建对象的时候,我们给一块内存区域起一个名字,然后这个名字就是我们创建的对象的引用,只要我们“叫”这个名字,计算机就知道我们在对哪一块内存区域进行操作。同理,方法也有名字,只是它的名字不是代表一块存储区域,而是代表一个动作。

  在人类的语言中,我们会说:洗衣、洗碗、洗车,对于同一个动作“洗”,我们并没有因为后面接的具体名词的不同赋予这个动作不同的名字,比如“衣洗”衣,“碗洗”碗,“车洗”车。因为这是一种冗余,同一个动作“洗”,我们完全可以根据上下文来判定要洗的是什么。对于编程语言,我们可能调用print()方法来输出整型变量、输出浮点型变量、输出字符串等等,在c语言中针对不同的输出类型需要提供不同的函数名,而在Java中,我们则直接使用通用的print()方法即可。

  而另一个促使方法重载的原因就是构造函数,构造函数名必须与类名一致,但是如果我们需要多种对象的构造方法呢?这时候方法重载就是必须的了。

Java如何区分重载的方法?

  对于只有一个方法使用方法名,在调用它的时候,我们自然知道该调用哪个方法;但是如果有多个方法共用一个名字,如何区分要调用的是哪一个方法?Java的处理方式是,每个重载的方法都应该具有独一无二的参数列表,独一无二的参数列表包括参数的个数不同;参数的类型不同;参数的顺序不同。

  值得注意的是只有返回值类型不同,无法区分方法,例如有两个方法:

int f() { return 1; }
void f() { }

  这两个方法的签名是一样的(方法名+参数列表),只有返回值不同。当我们调用int x = f(); 时,我们知道肯定会调用返回值为int的方法int f(),但是当我们调用f();时,就不知道该调用哪一个方法了,因为Java允许有返回值的方法在调用时忽略其返回值。

基本数据类型的重载

  由于基本数据类型都能自动向上转型,结合重载来看,可能比较难以理解。以下通过举例来说明。

public class PrimitiveOverloading {
private void f1(char x) { System.out.print("f1(char) "); }
private void f1(byte x) { System.out.print("f1(byte) "); }
private void f1(short x) { System.out.print("f1(short) "); }
private void f1(int x) { System.out.print("f1(int) "); }
private void f1(long x) { System.out.print("f1(long) "); }
private void f1(float x) { System.out.print("f1(float) "); }
private void f1(double x) { System.out.print("f1(double) "); } private void f2(byte x) { System.out.print("f2(byte) "); }
private void f2(short x) { System.out.print("f2(short) "); }
private void f2(int x) { System.out.print("f2(int) "); }
private void f2(long x) { System.out.print("f2(long) "); }
private void f2(float x) { System.out.print("f2(float) "); }
private void f2(double x) { System.out.print("f2(double) "); } private void f3(short x) { System.out.print("f3(short) "); }
private void f3(int x) { System.out.print("f3(int) "); }
private void f3(long x) { System.out.print("f3(long) "); }
private void f3(float x) { System.out.print("f3(float) "); }
private void f3(double x) { System.out.print("f3(double) "); } private void f4(int x) { System.out.print("f4(int) "); }
private void f4(long x) { System.out.print("f4(long) "); }
private void f4(float x) { System.out.print("f4(float) "); }
private void f4(double x) { System.out.print("f4(double) "); } private void f5(long x) { System.out.print("f5(long) "); }
private void f5(float x) { System.out.print("f5(float) "); }
private void f5(double x) { System.out.print("f5(double) "); } private void f6(float x) { System.out.print("f6(float) "); }
private void f6(double x) { System.out.print("f6(double) "); } private void f7(double x) { System.out.print("f7(double) "); } private void testConstVal() {
System.out.print("5: ");
f1(5); f2(5); f3(5); f4(5); f5(5); f6(5); f7(5);
System.out.println();
} private void testChar() {
char x = 'x';
System.out.print("char: ");
f1(x); f2(x); f3(x); f4(x); f5(x); f6(x); f7(x);
System.out.println();
} private void testByte() {
byte x =0;
System.out.print("byte: ");
f1(x); f2(x); f3(x); f4(x); f5(x); f6(x); f7(x);
System.out.println();
} private void testShort() {
short x =0;
System.out.print("short: ");
f1(x); f2(x); f3(x); f4(x); f5(x); f6(x); f7(x);
System.out.println();
} private void testInt() {
int x =0;
System.out.print("int: ");
f1(x); f2(x); f3(x); f4(x); f5(x); f6(x); f7(x);
System.out.println();
} private void testLong() {
long x =0;
System.out.print("long: ");
f1(x); f2(x); f3(x); f4(x); f5(x); f6(x); f7(x);
System.out.println();
} private void testFloat() {
float x =0;
System.out.print("float: ");
f1(x); f2(x); f3(x); f4(x); f5(x); f6(x); f7(x);
System.out.println();
} private void testDouble() {
double x =0;
System.out.print("double: ");
f1(x); f2(x); f3(x); f4(x); f5(x); f6(x); f7(x);
System.out.println();
} public static void main(String[] args) {
PrimitiveOverloading p = new PrimitiveOverloading();
p.testConstVal();
p.testChar();
p.testByte();
p.testShort();
p.testInt();
p.testLong();
p.testFloat();
p.testDouble();
}
} result:
5: f1(int) f2(int) f3(int) f4(int) f5(long) f6(float) f7(double)
char: f1(char) f2(int) f3(int) f4(int) f5(long) f6(float) f7(double)
byte: f1(byte) f2(byte) f3(short) f4(int) f5(long) f6(float) f7(double)
short: f1(short) f2(short) f3(short) f4(int) f5(long) f6(float) f7(double)
int: f1(int) f2(int) f3(int) f4(int) f5(long) f6(float) f7(double)
long: f1(long) f2(long) f3(long) f4(long) f5(long) f6(float) f7(double)
float: f1(float) f2(float) f3(float) f4(float) f5(float) f6(float) f7(double)
double: f1(double) f2(double) f3(double) f4(double) f5(double) f6(double) f7(double)

  从上述结果来看,常量5会被当做int,如果重载的方法中含有参数类型是int的,就会调用该方法;如果某个变量的数据类型小于重载方法中所有的数据类型,则该变量会向上转型;char类型比较特殊,如果参数类型不含char,则char会向上转型为int,然后按照int类型的规则来转型。

  如果某个变量的数据类型大于重载方法中所有数据类型呢?我们知道向上转型是会自动发生的,但是向下转型却不会,它需要进行强制类型转换。如果不进行转换直接调用,则无法通过编译。

  以下是向下转型时的正确使用方法,在上述实例中添加方法:

private void testWideDouble() {
double x = 0;
System.out.print("double argument: ");
f1((char) x); f1((byte) x); f1((short) x); f1((int) x); f1((long) x); f1((float) x); f1(x);
System.out.println();
}

  在main函数中调用它

p.testWideDouble();

result:
double argument: f1(char) f1(byte) f1(short) f1(int) f1(long) f1(float) f1(double)

方法重载(method overloading)的更多相关文章

  1. java中的方法覆盖(Overriding)和方法重载(Overloading)是什么意思?重写跟重载的区别?

    java中的方法重载发生在同一个类里面两个或者多个方法的方法名相同但是参数不同的情况.与此相对,方法覆盖是说子类重新定义了父类的方法.方法覆盖必须有相同的方法名,参数列表和返回类型. 覆盖者可能不会限 ...

  2. Java基础03 构造器与方法重载

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在方法与数据成员中,我们提到,Java中的对象在创建的时候会初始化(initial ...

  3. Java知多少(22)方法重载

    在Java中,同一个类中的多个方法可以有相同的名字,只要它们的参数列表不同就可以,这被称为方法重载(method overloading). 参数列表又叫参数签名,包括参数的类型.参数的个数和参数的顺 ...

  4. [Java学习] Java方法重载

    在Java中,同一个类中的多个方法可以有相同的名字,只要它们的参数列表不同就可以,这被称为方法重载(method overloading). 参数列表又叫参数签名,包括参数的类型.参数的个数和参数的顺 ...

  5. Java基础03 构造器与方法重载(转载)

    显式初始化要求我们在写程序时就确定初始值,这有时很不方便.我们可以使用构造器(constructor)来初始化对象.构造器可以初始化数据成员,还可以规定特定的操作.这些操作会在创建对象时自动执行. 定 ...

  6. java Vamei快速教程03 构造器和方法重载

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在方法与数据成员中,我们提到,Java中的对象在创建的时候会初始化(initial ...

  7. Java-Runoob-高级教程-实例-方法:01. Java 实例 – 方法重载

    ylbtech-Java-Runoob-高级教程-实例-方法:01. Java 实例 – 方法重载 1.返回顶部 1. Java 实例 - 方法重载  Java 实例 先来看下方法重载(Overloa ...

  8. C#中方法,方法声明,方法调用和方法重载!

      一,定义:方法是具有名称的可执行代码块. 二,方法的声明:声明方法的语法包括以下五个部分: 1,访问权限修饰符,这个是可选的参数,默认值是私有访问private,即只能从声明它的类的内部访问. 2 ...

  9. Java 实例 - 方法重载

    先来看下方法重载(Overloading)的定义:如果有两个方法的方法名相同,但参数不一致,哪么可以说一个方法是另一个方法的重载. 具体说明如下: 方法名相同 方法的参数类型,个数顺序至少有一项不同 ...

随机推荐

  1. 实现当前目录下开启CMD

    我们都知道在WIN7下,可以按shift+鼠标右键->在此处打开命令窗口 或者在 输入cmd,回车 那么,怎样去实现这样的功能呢? //当前目录下开启CMD #include <stdio ...

  2. POJ_1363_模拟

    题目描述: 列车出入站是一种栈的机制,每组数据给予一个n,进站按1-n顺序,给定一组出站顺序,判断能否实现. 思路: 直接用了queue,in记录当前准备入站的列车编号,out记录已经出站的辆数+1. ...

  3. EMC networker nmm can restore and recover sqlserver as different name to different location

    EMC networker nmm can restore and recover sqlserver as different name to different location That is ...

  4. 技术|Android安装包优化

    版权声明 1.本文版权归原作者所有,转载需注明作者信息及原文出处. 2.本文作者:赵裕(vimerzhao),永久链接:https://github.com/vimerzhao/vimerzhao.g ...

  5. 题解 SP375 【QTREE - Query on a tree】

    \[ \texttt{Preface} \] 这题在 \(\text{Luogu}\) 上竟然不能交 \(C++\) ,会一直 \(Waiting\) ,只能交非 \(C++\) 的语言. 所以打完了 ...

  6. 【算法】混合流体模拟demo

    展示一个流体模拟算法的实现 地址:http://www.iqiyi.com/w_19rzs1anol.html 采用C++编写,Blender渲染. 截图 参考文献 REN, B., LI, C., ...

  7. [Effective Java 读书笔记] 第三章类和接口 第十三 -- 十四条

    第十三条 使类和成员的可访问性最小化 总得来说,我们应该尽量将成员的访问范围限制到最小!有利于解耦,开发.测试和优化都能够更加独立. 对于成员(域,方法,嵌套类和嵌套接口),有四种可能的访问级别,访问 ...

  8. GPU 版 TensorFlow failed to create cublas handle: CUBLAS_STATUS_ALLOC_FAILED

    原因: 使用 GPU 版 TensorFlow ,并且在显卡高占用率的情况下(比如玩游戏)训练模型,要注意在初始化 Session 的时候为其分配固定数量的显存,否则可能会在开始训练的时候直接报错退出 ...

  9. vue-cli项目引入jquery和bootstrap

    1.安装插件 npm install jquery --save npm install bootstrap --save npm install popper.js --save //提示框插件,b ...

  10. python之基础中的基础(二)

    1.字典 创建字典,alien_0={'color':'green','points':5}其中由一个又一个的“键-值”对组成. 访问键-值对相应的值,print(alien_0['color']), ...