重写与重载编译时运行时不同之处

在我们平时在java基础学习到多态的时候我们知道一个父类引用指向子类对象的时候,编译时看父类,运行时看子类。那么抱着这个认识看下下面这个demo,以及给你带来怎么样的思考?



    public class Demo3 {

public static String  classmodify(Set<?> s){
    return "set";
}
public static String  classmodify(List<?> s){
    return "List";
}
public static String  classmodify(Collection<?> s){
    return "Collection";
}
public static void main(String[] args) {
    Collection<?>[] collection={
            new HashSet<String>(),
            new ArrayList<BigDecimal>(),
            new HashMap<String,String>().values()

    };

    for (Collection<?> collection2 : collection) {
        System.out.println(classmodify(collection2));
    }

}

}


打印
Collection
Collection
Collection

   因为要调用哪个重载是在编译器做的决定,在for循环的三次中编译时期的类型都是相同的Collection,每次迭代的运行时期的类型是不相同的,但这个不影响重载方法的选择。


这里写图片描述


这个与我们多态的父类引用指向子类对象,编译时看父类,运行时看子类不同的是,在重载的方法选择过程中,对象的运行时类型并不影响哪个重载版本被执行,选择工作是在编译时期完成的,完全基于参数的编译时期的类型。
但是多态的父类引用指向子类对象与这个不一样的,举个例子。

public class Fu {
        String  name(){
            return "fu";
        }
}
public class Zi extends Fu {
        String  name(){
            return "zi";
        }
}

public class Sun extends Zi {
    String  name(){
        return "Sun";
    }
}

public static void main(String[] args) {
        ArrayList<Fu> list = new ArrayList<Fu>();
        list.add(new Fu());
        list.add(new Zi());
        list.add(new Sun());
        for (Fu item : list) {
            System.out.println(item.name());
        }
    }
}


打印结果是:

fu
zi
Sun

原因
:尽管每次循环迭代过程中编译时期的类型都是Fu,运行时是各自的类型,当调用被覆盖的方法时,对象编译时期的类型不影响哪个方法被执行

想要看这个引用的运行时类型

System.out.println(collection2 instanceof Set ?"set":collection2 instanceof List?"list":collection2 instanceof Collection<?>?"Collection<?>":"");
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值