简体   繁体   English

在方法重载中传递不同数据类型的值

[英]Passing values of different data types in Method Overloading

I pass a double value to the method that is being overloaded but it takes it as float and invokes the method for finding area of square. 我将一个双精度值传递给正在重载的方法,但它将其视为float并调用该方法以查找平方面积。 Float values should have an "f" to their end to be considered float right? 浮点值的末尾应带有“ f”,才算是浮点值? so why does my program invoke float 'area of square' when it's supposed to invoke 'area of circle'? 那么为什么我的程序在应该调用“圆形区域”时为什么调用浮动“方形区域”呢?

public class App {
    public void calArea(float a) {
        System.out.println("Area of square is Side x Side : " + a * a);
    }

    public void calArea(float a, float b) {
        System.out.println("Area of rectangle is length x width" + a * b);
    }

    public void calArea(double r) {
        double area = (Math.PI * r * r);
        System.out.println("Area of circle is Radius x Radius x PI : " + area);
    }

    public static void main(String[] args) {

        App app = new App();

        app.calArea(5);
    }

}

I just post my comment as an answer, because it is the only way to resolve your problem without casting. 我只是将我的评论发布为答案,因为这是解决问题而无需强制转换的唯一方法。

Instead of using double and float to distinguish what areas should be calculated. 而不是使用doublefloat来区分应计算的面积。 Just name them differently . 只是用不同的名字命名 This will remove a lot of headache when seeing your code. 看到您的代码时,这将消除很多麻烦。

Will app.calArea(5) calculate the area of a circle or a square? app.calArea(5)计算圆形或正方形的面积吗?

So just change your code to this: 因此,只需将代码更改为此:

public class App {
    public void calAreaSquare(double a) {
        System.out.println("Area of square is Side x Side : " + a * a);
    }

    public void calAreaRectangle(double a, double b) {
        System.out.println("Area of rectangle is length x width" + a * b);
    }

    public void calAreaCircle(double r) {
        double area = (Math.PI * r * r);
        System.out.println("Area of circle is Radius x Radius x PI : " + area);
    }

    public static void main(String[] args) {

        App app = new App();

        app.calAreaCircle(5);
    }
}

I would also suggest just using double only, for the enhanced precision. 我还建议仅使用double来提高精度。

Simplest way to invoke method of 'area of circle' is just by calling from main method as " app.calArea(5d); ". 调用“圆形区域”方法的最简单方法就是从main方法中调用“ app.calArea(5d); ”。 By writing 5d or 5.0d area of circle method will be called because the value 5d is considered as double. 通过写入5d或5.0d面积的圆将被调用,因为值5d被视为两倍。 And if you want to invoke method of 'area of square', you can do it in either way by (1) app.calArea(5f); 如果要调用“平方面积”方法,则可以通过(1) app.calArea(5f);中的任一种方法来实现 or (2) app.calArea(5) . 或(2) app.calArea(5)

So, if you want to continue with your method overloading and invoke 'area of circle' you can do it in this way 因此,如果您想继续进行方法重载并调用“圆形区域”,可以采用这种方式

public class App {
    public void calArea(float a) {
        System.out.println("Area of square is Side x Side : " + a * a);
    }

    public void calArea(float a, float b) {
        System.out.println("Area of rectangle is length x width" + a * b);
    }

    public void calArea(double r) {
        double area = (Math.PI * r * r);
        System.out.println("Area of circle is Radius x Radius x PI : " + area);
    }

    public static void main(String[] args) {

        App app = new App();

        app.calArea(5d);
    }

}

Here are some quotes from the language spec that explains this behaviour. 以下是语言规范中的一些引语来解释此行为。

Section 15.12.2.5 Choosing the Most Specific Method 15.12.2.5节选择最具体的方法

If more than one member method is both accessible and applicable to a method invocation, it is necessary to choose one to provide the descriptor for the run-time method dispatch. 如果多个成员方法既可访问又可应用于方法调用,则必须选择一个成员方法来为运行时方法分派提供描述符。 The Java programming language uses the rule that the most specific method is chosen. Java编程语言使用选择最具体方法的规则。 The informal intuition is that one method is more specific than another if any invocation handled by the first method could be passed on to the other one without a compile-time error. 非正式的直觉是, 如果第一种方法处理的任何调用都可以传递给另一个方法而没有编译时错误 ,则一个方法比另一种方法更具体

In your case, both calArea(float) and calArea(double) are applicable for a single int argument ( int can be converted to either float or double through a primitive widening conversion). 在您的情况下, calArea(float)calArea(double)都适用于单个int参数(可以通过原始扩展转换将int转换为floatdouble )。

Now the compiler needs to decide which is more specific. 现在,编译器需要确定哪个更具体。 In the end, the compiler chose calArea(float) because it is more specific than calArea(double) . 最后,编译器选择了calArea(float)因为它比calArea(double)更具体。

Every call that is applicable to calArea(float) is applicable to calArea(double) (implicit primitive widening conversion from float to double ), but not vice versa (you need a cast to convert from double to float ). 适用于calArea(float)每个调用都适用于calArea(double) (从floatdouble隐式原始加宽转换),反之亦然(您需要calArea(double)转换从doublefloat转换)。

Therefore the compiler chose the calArea(float) overload. 因此,编译器选择了calArea(float)重载。

to answer "why does my program invoke float 'area of square' when it's supposed to invoke 'area of circle'?" 回答“为什么我的程序在应调用“圆区域”时为何调用浮点数“方形区域”?”

This is because the exact matched method which accept int argument is not found hence based on widening, nearest method that matched is called(here its float) widening happens in below order byte - > short - > int - > long - > float - > double 这是因为未找到接受int参数的精确匹配方法,因此基于加宽,将调用匹配的最接近的方法(此处是其float)加宽发生在以下顺序字节中-> short-> int-> long-> float->双

in your case its (int - > long - > float - > double) as you are passing int argument hence nearest match is a method that accepts float argument hence calArea(float a) is called 在您的情况下,当您传递int参数时,其(int-> long-> float-> double)因此最接近的匹配是一种接受float参数的方法,因此调用了calArea(float a)

[to check this try including a method that accepts long argument and you will see it will get a chance to execute instead of earlier method that accepts float argument] [要检查此尝试是否包含接受长参数的方法,您将看到它有机会执行,而不是较早的接受float参数的方法。

eg 例如

  1. public void calArea(int a) { System.out.println("int"); public void calArea(int a){System.out.println(“ int”); } }

  2. public void calArea(long a) { System.out.println("long"); public void calArea(long a){System.out.println(“ long”); } }

  3. public void calArea(float a) { System.out.println("float"); public void calArea(float a){System.out.println(“ float”); } }
  4. public void calArea(double a) { System.out.println("double"); public void calArea(double a){System.out.println(“ double”); } }

method call is - calArea(5); 方法调用是-calArea(5); case 1: lets say no method commented here method accepting int argument will be called. 情况1:假设这里没有注释的方法将被调用接受int参数的方法。

case 2: now comment /remove first method (accepting int argument) here method accepting long argument will be called. 情况2:现在注释/删除第一个方法(接受int参数),这里将调用接受长参数的方法。

case 3: now again comment method 1 and 2 method here method accepting float argument will be called. 情况3:现在再次注释方法1和2方法,这里将调用接受float参数的方法。 and so on... 等等...

As you are passing int value not double.... so 'area of square' is being calculated. 当您传递int值时,不能将double值...。因此正在计算“平方面积”。 For 'area of circle' you have to pass decimal value as argument while calling the function. 对于“圆形区域”,您必须在调用函数时将十进制值作为参数传递。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM