方法重载(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)的定义:如果有两个方法的方法名相同,但参数不一致,哪么可以说一个方法是另一个方法的重载. 具体说明如下: 方法名相同 方法的参数类型,个数顺序至少有一项不同 ...
随机推荐
- GDI+如何判断一个点是否在区域内
https://msdn.microsoft.com/en-us/library/windows/desktop/ms533826(v=vs.85).aspx The purpose of hit t ...
- Features for Multi-Target Multi-Camera Tracking and Re-identification论文解读
解读一:Features for Multi-Target Multi-Camera Tracking and Re-identification Abstract MTMCT:从多个摄像头采集的视频 ...
- java12类的无参方法
package com.jh.test01; public class AutoLion { // 属性: 颜色 黄色 String color = "黄色"; // 函数:跑,叫 ...
- thinkphp远程执行漏洞的本地复现
thinkphp远程执行漏洞的本地复现 0X00漏洞简介 由于ThinkPHP5 框架控制器名 没有进行足够的安全监测,导致在没有开启强制路由的情况下,可以伪装特定的请求可以直接Getshell(可以 ...
- java中深拷贝浅拷贝简析
Java中对象的创建 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象.所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象.那 ...
- wireshark抓包思维导图---新手推荐
- 申请Let’s Encrypt通配符HTTPS证书(certbot ACME v2版)
1.获取certbot-auto# 下载 # 下载 wget https://dl.eff.org/certbot-auto # 设为可执行权限 chmod a+x certbot-auto 2.开始 ...
- VFP 的 SPT 起跳 -- 陈纯(BOE数据网络工作室)
细节描述 Visual FoxPro 的 SPT 技术快速入门 说在前面熟悉 Fox 的朋友都知道,在 VFP 里我们可以使用远程视图 (Remote View) 和 SPT(SQL Pass Thr ...
- chromedriver和firefox driver的安装过程
环境:ubuntu14.04, python2.7 selenium2.0 文章参考出处:http://blog.csdn.net/heybob/article/details/52922645 ch ...
- JMeter-命令行模式压测
前言 使用非GUI模式,即命令行模式运行jmeter测试脚本能够大大缩减系统资源,今天跟小伙伴们讲一下JMeter如何在命令行模式进行压测吧! 一:配置好JDK和JMeter的环境变量(过程略) 二: ...