java 重载 参数,Java中使用不同参数数据类型的继承和重载方法

When I was analyzing a simple java code related with overloading and inheritance I expected to recieve an output that overloads matching the argument's data types. But it doesn't work that way.

Code:

class A {

public int calc (double num){

System.out.println("calc A");

return (int)(num+1);}

}

class B extends A{

public int calc (long num){

System.out.println("calc B");

return (int)(num+2);}

}

class C extends B{

public int calc (int num){

System.out.println("calc C");

return num+3;}

}

class D extends C{

public int calc (float num){

System.out.println("calc D");

return (int)(num+4);}

}

class Program{

public static void main(String[] args){

int num1=10;

long num2 = num1;

Object o1 = num1;

System.out.println("num1 Type: "+o1.getClass().getName());

Object o2 = num2;

System.out.println("num2 Type: "+o2.getClass().getName());

A a1=new D();

A a2=new D();

System.out.println("a1 Type: "+a1.getClass().getName());

System.out.println("a2 Type: "+a2.getClass().getName());

int result = a1.calc(num1)+a2.calc(num2);

System.out.println("Number: "+result);

}

}

Output:

num1 Type: java.lang.Integer

num2 Type: java.lang.Long

a1 Type: D

a2 Type: D

calc A

calc A

Number: 22

I was testing the code here:

ideone

解决方案

Your main question seems to be about why the type outputs don't match with the formal types. This is entirely intentional, and it's what makes object oriented programming so powerful.

When a method is invoked on an instance, the runtime system looks at the actual type of the instance, and looks up the method to call based on its actual type, rather than on its formal type.

If this weren't the case, you wouldn't be able to get anything useful done. You want to be able to declare an abstract class A, with concrete classes B and C hanging off it that implement the details in different ways. But you also want to be able to declare variables of type A, without caring where they've come from, and whether they're actually of type B or type C. You can then invoke methods that are part of the contract of A, and it'll do the right thing: something that's really a B will invoke B's implementation, and likewise for C.

As for why you end up invoking A's calc method rather than D's, this is again because of the way polymorphism works. The formal type of the variables is A; so when you invoke .calc(), the type system will:

find the most appropriate method in class A to match the call at compile time;

see whether that has been overridden between A and the actual type at runtime;

call the overridden version if there is one, or A's version if not.

But you haven't overridden the calc() method at all: you've supplied methods with different signatures. So in step 1 (at compile time) the type system finds A.calc(double); in step 2 (at runtime) it discovers that this hasn't been overridden further down the class hierarchy; in step 3 (runtime) it therefore invokes A's version.

Overloads are resolved at compile time based on formal types; overrides are resolved at runtime based on actual types.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值