方法重载(method overloading)
为什么需要方法重载?
在编程语言中,名字的使用很重要。创建对象的时候,我们给一块内存区域起一个名字,然后这个名字就是我们创建的对象的引用,只要我们“叫”这个名字,计算机就知道我们在对哪一块内存区域进行操作。同理,方法也有名字,只是它的名字不是代表一块存储区域,而是代表一个动作。
在人类的语言中,我们会说:洗衣、洗碗、洗车,对于同一个动作“洗”,我们并没有因为后面接的具体名词的不同赋予这个动作不同的名字,比如“衣洗”衣,“碗洗”碗,“车洗”车。因为这是一种冗余,同一个动作“洗”,我们完全可以根据上下文来判定要洗的是什么。对于编程语言,我们可能调用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)的更多相关文章
- java中的方法覆盖(Overriding)和方法重载(Overloading)是什么意思?重写跟重载的区别?
java中的方法重载发生在同一个类里面两个或者多个方法的方法名相同但是参数不同的情况.与此相对,方法覆盖是说子类重新定义了父类的方法.方法覆盖必须有相同的方法名,参数列表和返回类型. 覆盖者可能不会限 ...
- Java基础03 构造器与方法重载
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在方法与数据成员中,我们提到,Java中的对象在创建的时候会初始化(initial ...
- Java知多少(22)方法重载
在Java中,同一个类中的多个方法可以有相同的名字,只要它们的参数列表不同就可以,这被称为方法重载(method overloading). 参数列表又叫参数签名,包括参数的类型.参数的个数和参数的顺 ...
- [Java学习] Java方法重载
在Java中,同一个类中的多个方法可以有相同的名字,只要它们的参数列表不同就可以,这被称为方法重载(method overloading). 参数列表又叫参数签名,包括参数的类型.参数的个数和参数的顺 ...
- Java基础03 构造器与方法重载(转载)
显式初始化要求我们在写程序时就确定初始值,这有时很不方便.我们可以使用构造器(constructor)来初始化对象.构造器可以初始化数据成员,还可以规定特定的操作.这些操作会在创建对象时自动执行. 定 ...
- java Vamei快速教程03 构造器和方法重载
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在方法与数据成员中,我们提到,Java中的对象在创建的时候会初始化(initial ...
- Java-Runoob-高级教程-实例-方法:01. Java 实例 – 方法重载
ylbtech-Java-Runoob-高级教程-实例-方法:01. Java 实例 – 方法重载 1.返回顶部 1. Java 实例 - 方法重载 Java 实例 先来看下方法重载(Overloa ...
- C#中方法,方法声明,方法调用和方法重载!
一,定义:方法是具有名称的可执行代码块. 二,方法的声明:声明方法的语法包括以下五个部分: 1,访问权限修饰符,这个是可选的参数,默认值是私有访问private,即只能从声明它的类的内部访问. 2 ...
- Java 实例 - 方法重载
先来看下方法重载(Overloading)的定义:如果有两个方法的方法名相同,但参数不一致,哪么可以说一个方法是另一个方法的重载. 具体说明如下: 方法名相同 方法的参数类型,个数顺序至少有一项不同 ...
随机推荐
- 关于java String类的getBytes(String charsetName)和String(byte[] bytes, String charsetName)
public byte[] getBytes(Charset charset) Encodes this String into a sequence of bytes using the given ...
- 说说GAN(生成式对抗网络)
在Auto-encoder中,input data通过一个encoder神经网络得到一个维度的较低的向量,称这个向量为code,code经过一个decoder神经网络后输出一个output data. ...
- HDU6446 Tree and Permutation(树、推公式)
题意: 给一棵N个点的树,对应于一个长为N的全排列,对于排列的每个相邻数字a和b,他们的贡献是对应树上顶点a和b的路径长,求所有排列的贡献和 思路: 对每一条边,边左边有x个点,右边有y个点,x+y= ...
- EMC NW NMM to backup MS AG
To use EMC NW NMM to backup MS SQL always on database, that is a simple and safe way to protector da ...
- 微信小程序中的图表构建
第一 html中的代码 <view class="container"> <canvas canvas-id="lineCanvas" bin ...
- node - MongoDB数据库
mongod 安装配置 在Mongodb官网下载最新版本的Mongodb下载地址 下载msi的window安装包,可以装到C盘或者D盘目录下 配置 由于我是安装在D盘的环境下 D:\Program F ...
- Shell脚本 统计店中店导出数据
有一个数据文件 yue.csv 是这样的 #head yue.csv 日期,商家名称,要求在线数,当天在线数,要求在线时长,在线时长达标数, ……"2017-12-31&quo ...
- monkey命令行测试
一. 什么是Monkey monkey是google提供的一个用于稳定性与压力测试的命令行工具.monkey程序由android系统自带,位于/sdcard/system/framework/monk ...
- vue-cli项目引入jquery和bootstrap
1.安装插件 npm install jquery --save npm install bootstrap --save npm install popper.js --save //提示框插件,b ...
- C语言四
c语言循环结构 为什么用循环? C语言中的循环主要分为三种:while循环,do...while循环 for循环 while循环:先判断条件是否成立,如果条件成立将执行其下的循环体,如果条件不成立一次 ...