简体   繁体   中英

Method overloading with float and double type in super class and base class

Why float method is not considered of Derive class in below program?

In the below program when I assign derive object to base class at that time base.f(20) consider the Derive class int method but base.f(20.0f) is not considered Derive class float method.

Can you guys explain me what is the logic behind this?

public class Tricky3 {

    public static void main(String[] args) {
        Derive derive = new Derive();
        System.out.println(derive.f(10));
        System.out.println(derive.f(10.0f));

        System.out.println("------------------New Logic-----------------");
        Base base = new Derive();
        System.out.println(base.f(20));
        System.out.println(base.f(20.0f));

    }
}

class Base {
    public int f(int i) {
        System.out.print("Base f (int): ");
        return i + 3;
    }
    public double f(double i) {
        System.out.print("Base f (double) : ");
        return i + 3.3;
    }
}

class Derive extends Base{
    public float f(float i) {
        System.out.print("Derive f (float) : ");
        return i + 3.3f;
    }
    public int f(int i) {
        System.out.print("Derive f (int): ");
        return i + 3;
    }
}

Output

Derive f (int): 13

Derive f (float) : 13.3

------------------New Logic-----------------

Derive f (int): 23

Base f (double) : 23.3

When you choose to declare a style

Parent p = new Child();

You are accessing members from parent and implementations from children execute runtime. Since your parent doesn't have method with float type it chosen from Base . If you override the same method in children, that executes.

You are using Base base reference variable and Derive derive object.

base.f(20.0f) will try to find Base.f(float) method signature, when it cannot find Base.f(float) the Dynamic Binding with Derive.f(float) cannot happen, then it will search for closest method which can support base.f(20.0f) call which is Base.f(double) .

If you declare f(float) in Base class then Dynamic Binding will happen and Derive.f(float) will be called.

The problem can be reduced to the following snippet:

class Base {
    public double f(double x) {
        System.out.println("Base.f");
        return x;
    }
}

class Derived extends Base {
    public float f(float x) {
        System.out.println("Derived.f");
        return x;
    }
}

public class Main {
    public static void main(String[] args) {
        new Derived().f(1.0f);           // Derived.f
        ( (Base)new Derived() ).f(1.0f); // Base.f
    }
}

When evaluating new Derived().f(1.0f) the compiler has the choice

  • to implicitly convert the float parameter into a double and call Base.f(double) , or
  • to call Derived.f(float) without conversion.

The compiler chooses the Derived.f(float) overload because it manages without conversion.

When evaluating ( (Base)new Derived() ).f(1.0f) the compiler no longer knows about the Derived.f(float) overload and is forced to do the conversion and then call Base.f(double) .

The behavior would be different if Derived.f and Base.f had the same signature. Then the method would be overwritten and both statements would call Derived.f :

class Base {
    public double f(double x) {
        System.out.println("Base.f");
        return x;
    }
}

class Derived extends Base {
    public double f(double x) {
        System.out.println("Derived.f");
        return x;
    }
}

public class Main {
    public static void main(String[] args) {
        new Derived().f(1.0f);           // Derived.f
        ( (Base)new Derived() ).f(1.0f); // Derived.f
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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