• java覆盖


    一、java覆盖如何执行:编译看左边,运行看右边

    在子类方法覆盖父类方法时,在编译期,编译器会检查这个对象的引用类型是否含有此方法。如果没有则编译会出错,有则会通过编译。但在执行期,JVM寻找的不是引用指向的类型,而是堆上的对象。(即编译看左边,运行看右边)。

    1.子类方法覆盖了父类方法

    //Father类
    public class Father {
        
        public void turnOn(){
            System.out.println("父类方法turnOn执行");
        }
        
    }
    //Son类,继承了Father类
    public class Son extends Father {
        
        @Override
        public void turnOn() {
            System.out.println("子类方法turnOn执行");
        }
     
    }
    
    public class Demo {
        public static void main(String[] args) {
            Father f = new Son();
            f.turnOn();
        }
    }
    

    运行Demo类中的main()方法:

    在编译期,编译器会检查对象f的引用类型(即Father)是否有turnOn(),由于Father类有这个方法,于是编译器不会报错,程序编译成功。在运行期,究竟运行Father类的两个方法还是Son类的方法呢?JVM会从对象f开始向上找直到找到turnOn()为止,由于我们在Son类覆盖了turnOn(),所以JVM会执行Son类的turnOn()。

    2.父类引用不能调用子类特有的方法

    //将上面的Son.class修改成下面这个
    public class Son extends Father {
        @Override
        public void turnOn() {
            System.out.println("子类方法turnOn执行");
        }
    
        //定义一个只有子类有父类没有的方法
        public void sonFunction(){
            System.out.println("子类独有方法");
        }
    }
    

    修改Demo的main()为下图的代码,编译,可以看到编译器找不到sonFunction()。为什么呢?因为根据覆盖的原理,f的引用类型(Father)是没有sonFunction()方法的,所以就会编译报错。

    3.父类引用调用子类特有的方法?利用instanceof或抽象类

    下面只介绍instanceof,抽象类快忘光了,下次再补充...(反正应该没人看我的文章)。

    将Demo的代码修改成下图:

    public class Demo {
        public static void main(String[] args) {
            Father f = new Son();
            f.turnOn();
            if(f instanceof Son){
            //对象A instanceof B,如果对象A是类B的对象,则返回true,否则返回false
                Son s = (Son) f;//向下转型,将f由Father类的引用转为Son类的引用
                s.sonFunction();//调用Son类独有的方法
            }
        }
    }
    

    二、java子类方法覆盖父类方法应该遵守的规则

    1、参数必须要一样,且返回类型要兼容

    父类方法使用了哪种参数,覆盖此方法的子类也一定要使用相同的参数。不论父类的声明的返回类型是什么,子类必须声明返回一样的类型或该类型的子类型。

    2、不能降低方法的存取权限

    这代表存取权限必须相同,或者更为开放。举例来说,你不能在子类中覆盖一个公有方法并将它标记为私有。这会让JVM在编译期以为通过的是个公有方法,然后在执行期才会被JVM阻止存取。

    public class Father {
    
        public void turnOn(){
            System.out.println("父类方法turnOn执行");
        }
    
    }
    public class Son extends Father {
        @Override
        private void turnOn() {//此处报错!!!!报错信息如下图
            System.out.println("子类方法turnOn执行");
        }
    
    }
    

  • 相关阅读:
    数据库: Android使用JDBC连接数据库实现增 删 该 查 操作(8.0版本)
    SWA2G422&485JK2G基础篇: 手机APP通过APMACBind方式绑定W5500(以太网)设备,实现MQTT远程通信控制
    ESA2GJK1DH1K微信小程序篇: 微信小程序MQTT连接阿里云物联网平台
    ESA2GJK1DH1K基础篇: 阿里云物联网平台: 测试MQTT连接阿里云物联网平台
    ESA2GJK1DH1K微信小程序篇: 小程序MQTT底层优化
    ESP8266 SDK开发: 准备工作-硬件说明
    ESA2GJK1DH1K数据篇: 数据篇准备工作
    ESA2GJK1DH1K升级篇: 网页实现MQTT控制- 网页版MQTT通信控制ESP8266设备,网页版MQTT连接阿里云通信
    ESA2GJK1DH1K升级篇: 网页实现MQTT控制- 网页版MQTT调试助手
    单片机模块化程序: CRC校验
  • 原文地址:https://www.cnblogs.com/red-vel/p/12969459.html
Copyright © 2020-2023  润新知