您的位置:首页 > 编程语言 > Java开发

thinking in java学习笔记1——全面解读方法重载

2011-11-06 21:44 591 查看
之前学习C++时对于方法重载有了一点认识,最近看了java编程思想一书,对书中方法重载的章节进行了一番研习发现之前对于方法重载的认识很浅薄很片面,所以在此总结下最近关于方法重载的学习结果,希望能比较全面的解读下方法重载。

一,方法重载的基本认识:

学习之前我们需要了解什么是方法重载,方法名相同而参数不同的方法既是方法重载,简单而言就是让类以统一的方式处理不同类型数据的一种方法。举个例子就能直观的看出来了,例如:void show() {……};void show(String s) {……},例中定义了名字同为show的两个方法,可以看出他们的参数不同,这即为方法重载。

那么方法重载有什么作用呢?前面我们已经解读过构造器,有时程序中需要用到参数不同而方法名相同的构造器,如果直接定义那么就会产生错误,此时方法重载就发挥了很大的作用,计算机可以通过方法重载中传递的参数找到适合的构造器进行调用,从而实现功能。

下面给出个简单的例子加深下认识。

class Tree {
int height;
Tree() {
prt("Planting a seedling");
height = 0;
}
Tree(int i) {
prt("Creating new Tree that is "
+ i + " feet tall");
height = i;
}
void info() {
prt("Tree is " + height
+ " feet tall");
}
void info(String s) {
prt(s + ": Tree is "
+ height + " feet tall");
}
static void prt(String s) {
System.out.println(s);
}
}
public class Overloading {
public static void main(String[] args) {
for(int i = 0; i < 5; i++) {
Tree t = new Tree(i);
t.info();
t.info("overloaded method");
}
// Overloaded constructor:
new Tree();
}
} /*Output:
Creating new Tree that is 0 feet tall
Tree is 0 feet tall
Overloading method: Tree is 0 feet tall
Creating new Tree that is 1 feet tall
Tree is 1 feet tall
Overloading method: Tree is 1 feet tall
Creating new Tree that is 2 feet tall
Tree is 2 feet tall
Overloading method: Tree is 2 feet tall
Creating new Tree that is 3 feet tall
Tree is 3 feet tall
Overloading method: Tree is 3 feet tall
Creating new Tree that is 4 feet tall
Tree is 4 feet tall
Overloading method: Tree is 4 feet tall
Planting a seeding*/


创建Tree对象的时候,既可以不含参数,也可以用树的高度当参数。前者表示一颗树苗,后者表示已有一定高度的树木。要支持这种创建方式,得有一个默认构造器和一个采用现有高度作为参数的构造器。通过上述方法对于方法重载就有了基本的了解。现在便要知道该如何区分重载方法。

二,区分重载方法:

根据方法重载的定义可以看出,方法重载最大的区别在于参数不同,于是就有了以下几种区分方法:

1, 参数类型不同:void show(String s) {……};void show(int a) {……}。

2, 参数数目不同:void show(int a) {……};void show(int a,int b) {……}。

3, 参数顺序不同:void show(int a,String s) {……};void show(String s.int a) {……}。

这个内容相比比较简单所以就不用我苍白的文字赘述过多了。

接下来将要分享下新学到的关于方法重载的知识点。

三,基本类型的重载

这是个比较特殊的重载应用,我们通过例程分析:

public class PrimitiveOverloading {
static void prt(String s) {
System.out.println(s);
}
void f1(char x) { prt("f1(char)"); }
void f1(byte x) { prt("f1(byte)"); }
void f1(short x) { prt("f1(short)"); }
void f1(int x) { prt("f1(int)"); }
void f1(long x) { prt("f1(long)"); }
void f1(float x) { prt("f1(float)"); }
void f1(double x) { prt("f1(double)"); }
void f2(byte x) { prt("f2(byte)"); }
void f2(short x) { prt("f2(short)"); }
void f2(int x) { prt("f2(int)"); }
void f2(long x) { prt("f2(long)"); }
void f2(float x) { prt("f2(float)"); }
void f2(double x) { prt("f2(double)"); }
void f3(short x) { prt("f3(short)"); }
void f3(int x) { prt("f3(int)"); }
void f3(long x) { prt("f3(long)"); }
void f3(float x) { prt("f3(float)"); }
void f3(double x) { prt("f3(double)"); }
void f4(int x) { prt("f4(int)"); }
void f4(long x) { prt("f4(long)"); }
void f4(float x) { prt("f4(float)"); }
void f4(double x) { prt("f4(double)"); }
void f5(long x) { prt("f5(long)"); }
void f5(float x) { prt("f5(float)"); }
void f5(double x) { prt("f5(double)"); }
void f6(float x) { prt("f6(float)"); }
void f6(double x) { prt("f6(double)"); }
void f7(double x) { prt("f7(double)"); }
void testConstVal() {
prt(“ 5:");
f1(5);f2(5);f3(5);f4(5);f5(5);f6(5);f7(5);
}
void testChar() {
char x = 'x';
prt("char:");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
}
void testByte() {
byte x = 0;
prt("byte:");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
}
void testShort() {
short x = 0;
prt("short:");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
}
void testInt() {
int x = 0;
prt("int:");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
}
void testLong() {
long x = 0;
prt("long:");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
}
void testFloat() {
float x = 0;
prt("float:");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
}
void testDouble() {
double x = 0;
prt("double:");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
}
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();
}
} /*Output
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的提升将跳过byte和short型而直接提升成为int型。这是传入参数小于形式参数的情况,那如果是传入的实际参数大于重载方法声明的形式参数将会是以下这种情况。

public class Demotion {
static void prt(String s) {
System.out.println(s);
}
void f1(char x) { prt("f1(char)"); }
void f1(byte x) { prt("f1(byte)"); }
void f1(short x) { prt("f1(short)"); }
void f1(int x) { prt("f1(int)"); }
void f1(long x) { prt("f1(long)"); }
void f1(float x) { prt("f1(float)"); }
void f1(double x) { prt("f1(double)"); }
void f2(char x) { prt("f2(char)"); }
void f2(byte x) { prt("f2(byte)"); }
void f2(short x) { prt("f2(short)"); }
void f2(int x) { prt("f2(int)"); }
void f2(long x) { prt("f2(long)"); }
void f2(float x) { prt("f2(float)"); }
void f3(char x) { prt("f3(char)"); }
void f3(byte x) { prt("f3(byte)"); }
void f3(short x) { prt("f3(short)"); }
void f3(int x) { prt("f3(int)"); }
void f3(long x) { prt("f3(long)"); }
void f4(char x) { prt("f4(char)"); }
void f4(byte x) { prt("f4(byte)"); }
void f4(short x) { prt("f4(short)"); }
void f4(int x) { prt("f4(int)"); }
void f5(char x) { prt("f5(char)"); }
void f5(byte x) { prt("f5(byte)"); }
void f5(short x) { prt("f5(short)"); }
void f6(char x) { prt("f6(char)"); }
void f6(byte x) { prt("f6(byte)"); }
void f7(char x) { prt("f7(char)"); }
void testDouble() {
double x = 0;
prt("double argument:");
f1(x);f2((float)x);f3((long)x);f4((int)x);
f5((short)x);f6((byte)x);f7((char)x);//窄化转换
}
public static void main(String[] args) {
Demotion p = new Demotion();
p.testDouble();
}
} /*Output:
double argument:
f1(double)
f2(float)
f3(long)
f4(int)
f5(short)
f6(byte)
f7(char)*/


在这里可以看出来方法接受较小的基本类型作为参数。如果传入的实际参数较大,就得通过类型转换来执行窄化转换,在转换过程中可能丢失一些信息。这正是编译器强迫我们明确定义的原因——我们需明确表达想要转型的愿望。
四, 注意事项:
方法重载是很“单纯“的,用起来也很方便,没有太多的约束条件,但是要注意不能以返回值区分重载方法,而且注意方法重载与构造器的搭配,他们是”一对“不可轻易拆散,否则编译器就找不到相应的调用。
方法重载的东西基本上说的差不多了,想要更深入的理解还需要将理论上升到实践中。
敲这些代码不容易啊……最最要命的是这是第二次敲了,所以容我休息一会吧,哦对了,希望来过的朋友留下你的痕迹,我们多多交流,希望大家也能给出意见及建议,我仍旧处于长期学习阶段,希望大家多多指教……谢谢。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: