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

你好呀,我是沉默王二,(目前是)CSDN 周排名前十的博客专家。这是《教妹学 Java》专栏的第二十七篇,今天我们来谈谈 Java 中的方法重载——方法重载有哪几种形式?为什么改变返回类型不算是方法重载?可以重载 main 方法吗?

本专栏中的代码已收录到 GitHub github.com/itwanger ,里面还有我精心为你准备的一线大厂面试题。

三妹开学了,学的计算机软件编程。她学校离我家很近,坐公交车也就 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、什么隐式类型转换

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

如上图所示,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

继续来看示例:

/**
 * @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) 就会不知道该调用哪一个,对吧?

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

04、ending

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

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

二哥肝了两天两夜,《程序员不可或缺的软实力》第一版强势来袭,纯手敲,足足 20 万字精华文章,贯穿了我十余年的编程生涯,涉及到了生活和工作中的方方面面,如果你是迷茫的在校大学生,或者刚入职的新人,相信我的个人经历,可以给你带去一些思考,从而树立起正确的人生观和价值观。

那这份 PDF 该怎么获取呢?

链接:https://pan.baidu.com/s/1TA3txLvHxQNJEOJUHSZEqQ 密码:ps7z

如链接失效,请转至备用链接:https://shimo.im/docs/pJQv6qVcHqdYwrxx

最后,真心希望这份 PDF 能够对大家起到实质性的帮助,我也会在后面不断完善这本电子书,敬请期待。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沉默王二

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值