java的多态性

学了还蛮久的java,一直知道其具备面向对象的三个基本特征:继承、封装和多态。但是一直没怎么明白多态性。今天看了书,大概总结一下(感觉不是很全面)。

java中多态性分为动态多态性和静态多态性。静态多态性就是指方法的重载,是一个类的行为。动态多态性是指方法的重写,即多态是指在有继承关系的两个或两个以上的类的行为。

下面是一个重写的小Demo

public class DynamicTest {

    static abstract class Human{
        protected abstract void sayHello();
    }

    static class Man extends Human{

        @Override
        protected void sayHello() {
            System.out.println("man say hello");
        }

    }

    static class Woman extends Human{
        @Override
        protected void sayHello() {
            System.out.println("woman say hello");
        }
    }

    public static void main(String[] args) {
        Human man=new Man();
        Human woman=new Woman();
        man.sayHello();
        woman.sayHello();
        man=new Woman();
        man.sayHello();
    }

}

结果:
man say hello
woman say hello
woman say hello

以上Man类和Woman类重写了sayHello方法,属于重写。

下面来看下重载的匹配优先级

import java.io.Serializable;


public class Overload {

    public static void sayHello(Object arg){
        System.out.println("Object sayHello");
    }

    public static void sayHello(int arg){
        System.out.println("int sayHello");
    }

    public static void sayHello(char arg){
        System.out.println("char sayHello");
    }

    public static void sayHello(long arg){
        System.out.println("long sayHello");
    }

    public static void sayHello(Character arg){
        System.out.println("Character sayHello");
    }

    public static void sayHello(char...arg){
        System.out.println("char... sayHello");
    }

    public static void sayHello(Serializable arg){
        System.out.println("Serializable sayHello");
    }

    public static void main(String[] args) {
        sayHello('a');

    }

}

我们知道‘a’是一个char类型的数据,自然会寻找参数类型为char的重载方法
当把sayHello(char arg)注释掉时,会执行sayHello(int arg)重载方法,发生类型转换
当把sayHello(int arg)注释掉时,会执行sayHello(int arg)重载方法,发生类型转换
这时发生了两次自动类型转换,’a’转型成整数97,再转化为长整形97L,匹配了参数类型为long的重载。要是有float、double类型的重载,则按照char->int->long->float->double的顺序进行匹配。

当我们继续注释掉sayHello(long arg)时,那么会执行sayHello(Character arg)重载方法,这时发生一次自动装箱,’a’被包装为它的封装类型java.lang.Character,所以匹配到参数类型为Character的重载。
继续注释掉sayHello(Character arg),那么会执行sayHello(Serializable arg)重载方法。这时因为java.lang.Serializable是java.lang.Character类实现的一个接口,当自动装箱以后还是找不到箱类,但是找到箱类实现了的接口类型,所以紧接着又发生了一次自动转型。char可以转型成int,但是Character是绝不会转型成Integer的,它只能安全地转型为它实现的接口或父类。
继续注释掉sayHello(Serializable arg),那么会执行sayHello(char…arg)重载方法,可见变长参数的重载优先级是最低的,这时候字符’a’被当成一个数组元素。

本文参考《深入理解java虚拟机–JVM高级特性与最佳实践》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值