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
Base.f(double)
, orDerived.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.