zoukankan      html  css  js  c++  java
  • 方法重载(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) 
    
  • 相关阅读:
    路由的使用
    组件之间的参数传递
    vue组件的全局注册和局部注册
    git版本回退(回退至上个版本,回退至指定版本) git放弃本地所有未提交的修改
    vue工程中的文件
    新建vue项目(webpack-simple)
    NPM install -save 和 -save-dev 傻傻分不清
    动态增加表单vue element ui
    JAVA声明一个对象数组
    调用测试用
  • 原文地址:https://www.cnblogs.com/skye-you/p/9994739.html
Copyright © 2011-2022 走看看