方法重载

为什么会有方法重载
转自:http://www.cnblogs.com/thecatcher/p/5843970.html

OOP的编程方式就是让程序的逻辑更加接近现实世界的逻辑. 而在现实世界中,自然语言本身就是很强的冗余容错能力的. 比如,水有个方法叫洗. 那么在自然语言中,洗车,洗衣服…这都是洗这个方法. 映射到程序语言就是water.wash(car);,water.wash(clothes) 而不会说以洗车的方式洗车water.washCar(car)和以洗衣服的方式洗衣服water.washClothes(clothes)

java就提供了方法重载机制,一方面,更加接近自然语言逻辑. 另一方面,由于构造方法的存在. 每个类默认都有一个无参构造器,另外如果还想自定义一些构造器的话,由于构造方法的名称是甲鱼的臀部规定好了的. 那么就意味着每个构造器都要有相同的名字. 那么,这就必须要使用重载了.
方法签名

首先,一个方法的组成,一个方法由权限修饰符,返回值类型,方法名,形参列表,抛出异常类型和方法体组成.方法是依赖于一个类的,那么对于不同类的同名方法,在调用时是不存在歧义的,所以不用考虑.

JVM在调用方法的时候是通过方法签名来调用的. 换句话说同一个类中的方法签名应该是唯一的. 在构成方法的所有元素中,能唯一标识一个方法的组合都可以成为方法签名.
java的做法是将方法名和形参列表的组合作为方法签名. 为什么呢?因为在调用一个方法的时候,这两个是必须显式写出来的. 比如person.fun1(“tom”,29);

所以balabala说了那么多,方法签名就是函数名+形参列表
如何区分重载

明白了jvm是怎么调用方法的,就可以理解怎么区分重载了. 方法必须有独一无二的函数签名,对于重载方法来说,由于方法名是一样的. 那么能区分签名的就只剩形参列表了. 也就是说,重载方法必须有独一无二的形参列表. 可以是形参的类型不一样,可以是形参的个数不一样,也可以是形参顺序不一样. 但是一般不会采用顺序不一样. 因为这样会难以维护.
关于基本类型的重载

package ch5_init;

public class PrimitiveOverloading {
    public void print(String s){
        System.out.print(s+" ");
    }
    public void f1(char x){print("f1(char)");}
    public void f1(byte x){print("f1(byte)");}
    public void f1(short x){print("f1(short)");}
    public void f1(int x){print("f1(int)");}
    public void f1(long x){print("f1(long)");}
    public void f1(float x){print("f1(float)");}
    public void f1(double x){print("f1(double)");}

    public void f2(byte x){print("f2(byte)");}
    public void f2(short x){print("f2(short)");}
    public void f2(int x){print("f2(int)");}
    public void f2(long x){print("f2(long)");}
    public void f2(float x){print("f2(float)");}
    public void f2(double x){print("f2(double)");}

    public void f3(short x){print("f3(short)");}
    public void f3(int x){print("f3(int)");}
    public void f3(long x){print("f3(long)");}
    public void f3(float x){print("f3(float)");}
    public void f3(double x){print("f3(double)");}

    public void f4(int x){print("f4(int)");}
    public void f4(long x){print("f4(long)");}
    public void f4(float x){print("f4(float)");}
    public void f4(double x){print("f4(double)");}

    public void f5(long x){print("f5(long)");}
    public void f5(float x){print("f5(float)");}
    public void f5(double x){print("f5(double)");}

    public void f6(float x){print("f6(float)");}
    public void f6(double x){print("f6(double)");}  

    public void f7(double x){print("f7(double)");}

    public void testConstVal(){
        print("5: ");
        f1(5);f2(5);f3(5);f4(5);f5(5);f6(5);f7(5);
        System.out.println();
    }

    public void testChar(){
        char x = 'x';
        print("char: ");
        f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
        System.out.println();
    }

    public void testByte(){
        byte x = '0';
        print("byte: ");
        f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
        System.out.println();
    }

    public void tesShort(){
        short x = '0';
        print("short: ");
        f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
        System.out.println();
    }

    public void testInt(){
        int x = '0';
        print("int: ");
        f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
        System.out.println();
    }
    public void testLong(){
        long x = '0';
        print("long: ");
        f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
        System.out.println();
    }
    public void testFloat(){
        float x = '0';
        print("float: ");
        f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
        System.out.println();
    }
    public void testDouble(){
        double x = '0';
        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.tesShort();
        p.testInt();
        p.testFloat();
        p.testDouble();

    }           
}

这是书上一个很经典的例子. 运行它可以看出来.

常量5: 被当作int值处理.
char类型:如果无法找到接收char类型的方法. char类型会被自动转换成int型处理.
对于其他类型: 如果传入的实际类型小于方法声明的参数类型,那么会发生向上转型.
但是如果传入的实际类型大于方法声明的参数类型,需要显示的向下转型.

万事都要讲理. 类型转换,如果实际类型较小,那么向上转型是没有任何风险的. 精度不会受到影响,最多多占点空间,但是这对现代计算机而言不是什么大事儿. 但是如果实际类型较大,需要向下转型的时候,会发生精度丢失. jvm说,这锅我不背.

通过返回值来区分重载方法可不可以?
不可以,不用多说.因为返回值不是函数签名的一部分.是没有办法区分方法调用的.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值