天天看点

教妹学Java(三十):深入理解 Java 中的方法重载(Overloading)

三妹开学了,学的计算机软件编程。她学校离我家很近,坐公交车也就 10 站路的距离, 每逢周末她都会来找我,让我辅导她学习 Java。作为一名拥有十余年编程经验的程序员,再加上父母给我们的这份血缘关系,我觉得义不容辞。

“二哥,今天我们要学习的内容是‘方法重载(Overloading)’,对吧?”看来三妹已经提前预习了我上次留给她的作业。

“是的,三妹。如果一个类有多个名字相同但参数个数不同的方法,这就是所谓的方法重载。 ”我面带着朴实无华的微笑回答着她,“如果方法的功能是一样的,但参数不同,使用相同的名字可以提高程序的可读性。”

“假设,你现在需要完成一个加法运算,但参数的个数是不同的,如果你编写一个方法为 a(int i, int j) 进行两个数的相加,编写一个方法为 b(int i,int j, int k) 进行三个数的相加,因为两个方法名是不同的,别的程序员在调用这两个方法的时候就很迷惑,为什么功能相同,名字却不同呢?”

“方法重载刚好能够解决这个问题。”

----正儿八经的分割线,正文开始------------

01、方法重载有哪几种形式

在 Java 中,有两种方式可以达到方法重载的目的:

改变参数的数目;

改变参数的类型。

注意,改变方法的返回类型是不行滴。

1)改变参数的数目

/**
 * @author 微信搜「沉默王二」,回复关键字 PDF
 */
public class OverloadingByParamNum {
    public static void main(String[] args) {
        System.out.println(Adder.add(10, 19));
        System.out.println(Adder.add(10, 19, 20));
    }
}
class Adder {
    static int add(int a, int b) {
        return a + b;
    }
    static int add(int a, int b, int c) {
        return a + b + c;
    }
}      

在上面的示例中,Adder 类有两个方法,第一个 add 方法有两个参数,第二个 add 方法有三个参数。

2)改变参数的类型

/**
 * @author 微信搜「沉默王二」,回复关键字 PDF
 */
public class OverloadingByParamType {
    public static void main(String[] args) {
        System.out.println(Adder.add(10, 19));
        System.out.println(Adder.add(10.1, 19.2));
    }
}
class Adder {
    static int add(int a, int b) {
        return a + b;
    }
    static double add(double a, double b) {
        return a + b;
    }
}      

在上面的示例中,Adder 类有两个方法,第一个 add 方法的参数类型为 int,第二个 add 方法的参数类型为 double。

“二哥,改变参数的数目和类型都可以实现方法重载,为什么改变方法的返回值类型就不可以呢?”三妹很能抓住问题的重点嘛。

“因为仅仅改变返回值类型的话,编译器会懵逼。”我略带调皮的口吻回答她。

编译时报错优于运行时报错,所以当两个方法的名字相同,参数个数和类型也相同的时候,虽然返回值类型不同,但依然会提示方法已经被定义的错误。

02、 可以重载 main 方法吗

答案是肯定的,毕竟 main 方法也是个方法,只不过,Java 虚拟机在运行的时候只会调用带有 String 数组的那个 main 方法。

/**
 * @author 微信搜「沉默王二」,回复关键字 PDF
 */
public class OverloadingMain {
    public static void main(String[] args) {
        System.out.println("String[] args");
    }
    public static void main(String args) {
        System.out.println("String args");
    }
    public static void main() {
        System.out.println("无参");
    }
}      

程序输出结果如下所示:

String[] args

03、什么隐式类型转换

由于可以通过改变参数类型的方式实现方法重载,那么当传递的参数没有找到匹配的方法时,就会发生隐式的类型转换。

教妹学Java(三十):深入理解 Java 中的方法重载(Overloading)

如上图所示,byte 可以向上转换为 short、int、long、float 和 double,short 可以向上转换为 int、long、float 和 double,char 可以向上转换为 int、long、float 和 double,依次类推。

来看示例:

/**
 * @author 微信搜「沉默王二」,回复关键字 PDF
 */
public class OverloadingTypePromotion {
    void sum(int a, long b) {
        System.out.println(a + b);
    }

    void sum(int a, int b, int c) {
        System.out.println(a + b + c);
    }

    public static void main(String args[]) {
        OverloadingTypePromotion obj = new OverloadingTypePromotion();
        obj.sum(20, 20);
        obj.sum(20, 20, 20);
    }
}

      

执行 obj.sum(20, 20) 的时候,发现没有 sum(int a, int b) 的方法,所以此时第二个 20 向上转型为 long,所以调用的是 sum(int a, long b) 的方法。

再来看一个示例:

/**
 * @author 微信搜「沉默王二」,回复关键字 PDF
 */
public class OverloadingTypePromotion1 {
    void sum(int a, int b) {
        System.out.println("int");
    }
    void sum(long a, long b) {
        System.out.println("long");
    }
    public static void main(String args[]) {
        OverloadingTypePromotion1 obj = new OverloadingTypePromotion1();
        obj.sum(20, 20);
    }
}      

执行 obj.sum(20, 20) 的时候,发现有 sum(int a, int b) 的方法,所以就不会向上转型为 long,调用 sum(long a, long b)。

int

1

继续来看示例:

/**
 * @author 微信搜「沉默王二」,回复关键字 PDF
 */
public class OverloadingTypePromotion2 {
    void sum(long a, int b) {
        System.out.println("long int");
    }
    void sum(int a, long b) {
        System.out.println("int long");
    }
    public static void main(String args[]) {
        OverloadingTypePromotion2 obj = new OverloadingTypePromotion2();
        obj.sum(20, 20);
    }
}      

当有两个方法 sum(long a, int b) 和 sum(int a, long b),参数个数相同,参数类型相同,只不过位置不同的时候,会发生什么呢?

obj.sum(20, 20) 就会不知道该调用哪一个,对吧?

教妹学Java(三十):深入理解 Java 中的方法重载(Overloading)

不明确,很为难,究竟是把第一个 20 从 int 转成 long 呢,还是把第二个 20 从 int 转成 long,智障了!所以,不能写这样让编译器左右为难的代码。

04、ending

“三妹,关于 Java 中的方法重载,我们就学到这里吧,它的用法我相信你一定全部掌握了。”我揉一揉犯困的双眼,疲惫地给三妹说。

“好的,二哥,我这就去练习去。”三妹似乎意犹未尽,这种学习状态真令我感到开心。