Java覆盖、重载、隐藏相关知识

覆盖

发生在子类与父类的之间,指在在子类中声明一个和父类具有相同的方法名,参数列表,返回值,访问权限等的方法,即在子类中重新编写方法实现的功能。
构成覆盖需满足以下条件:

  1. 父类中的static方法不可以被覆盖;
  2. 父类中的final方法不可以被覆盖;
  3. 方法的签名、参数个数以及参数类型都要相同;
    对于返回类型要说明两点:
    1.如果返回类型是引用类型,则覆盖方法的返回类型可以声明为父类方法声明的返回类型的子类型;
    2.如果返回类型是基本类型,则覆盖方法的返回类型必须和父类方法的返回类型相同;
  4. 子类方法的访问权限要大于等于父类的访问权限;
  5. 子类方法可以改变某些方法修饰符,如:synchronized、native和strictfp。
  6. 子类方法的throws子句可以和父类方法不同,它列出的每一个异常类型都应该和父类中的异常类型相同或者是父类异常类型的子类;

重载

隐藏

隐藏现象发生在子类和父类之间,隐藏是针对父类中成员变量、静态方法和成员内部类而言。
当子类声明与父类中成员变量具有相同的变量名的变量时,则实现了对父类中成员变量的隐藏;
当子类声明了与父类中的静态成员方法具有相同的方法名,参数列表和相同的返回值时,则实现了对父类中静态方法的隐藏。方法隐藏只有一种形式,就是父类和子类存在相同的静态方法。
父类和子类拥有相同名字的属性或者方法时,父类的同名的属性或者方法形式上不见了,实际是还是存在的。
被隐藏的属性,在子类被强制转换成父类后,访问的是父类中的属性。

实例变量隐藏

    public static class Parent{
        int i = 0;
    }

    public static class Child extends Parent{
        int i = 1;
    }

    Parent p = new Child();
    Log.e("Test","p.i = "+p.i);

输出结果:p.i = 0
上面的代码中,Parent和Child中都定义了变量i,在main方法中,我们用Parent引用一个Child对象,如果实例变量与方法一样,允许被覆盖,那么打印的结果应该是1,但是实际的结果确是0。
但是如果我们在Child的方法中直接使用i,那么用的会是Child对象自己定义的实例变量i,这就是隐藏,Child对象中的i把Parent对象中的i给隐藏了,这条规则对于静态变量同样适用。

静态方法隐藏

    public static class Parent{
        public static void fun() {
            Log.e("Test","Parent.fun()");
        }
    }

    public static class Child extends Parent{
        public static void fun() {
            Log.e("Test","Child.fun()");
        }
    }
    Parent p = new Child();
    p.fun();

输出结果:Parent.fun()
这种现象也叫做隐藏。
父类的静态方法fun()是不能被重写的。
对于static方法,根本不存在像多态那样的动态分派机制,JVM 不会根据对象引用的实际类型来调用对应的重写方法。
最好避免用对象引用的方式来访问一个static方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寒江蓑笠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值