zoukankan      html  css  js  c++  java
  • Java继承,重写方法时改变方法的访问权限

      java中的方法天生具有继承多态特性,这点与C++有很大不同(需要在父类方发上加virtual关键字),但用起来确实方便了许多。

    最简单的继承多态

      声明一个接口BaseIF,只包含一个方法声明

    public interface BaseIF {
        void Access();
    }

      一个基类Base,基类实现了BaseIF接口,Access会调用Base类的public函数test()(实现类最好不要有自己的public函数,public函数应提到接口中,这里是为了说明问题方便)

    public class Base implements BaseIF {
        public void Access(){
            test();
        }
    
        public void test(){
            System.out.println("test in Base");
        }
    }

      一个派生类Derived,派生类重写test(),并保持test()的访问权限保持不变,依然为public

    public class Derived extends Base {
        //@Override
        public void test(){
            System.out.println("test in Derived");
        }
    }

      Demo入口测试代码

    public class Main {
    
        public static void main(String[] args) {
            BaseIF face = new Derived();
            face.Access();
        }
    }

      代码运行结果为:

      表明实际调用的test()方法来自Derived类,这便是继承多态的运行方式。

    降低派生类中test方法的访问权限

      将Derived类中test()的访问权限改为protect或者private,这时IDE会报编译错误,子类重写父类方法时,不可以降低方法的可访问性。

       

    public class Derived extends Base {
        @Override
        protected void test(){
            System.out.println("test in Derived");
        }
    }

      这一点其实很好理解,将测试代码写成下面这样。假如可以在Derived中降低test()的访问权限,那么base.test()应该调用基类的test()方法还是Derived类的?

      假如调用Base类的test(),那么子类重写test()变没有什么意义了;假如调用Derived类的,就会出现一个问题,Derived类的test()是protect方法,无法在类外部调用,假如通过基类可以调用派生类的protect或private方法,权限访问控制变出现了漏洞,所以最好的处理方式就是禁止在派生类中降低重写方法的可访问性

    public class Main {
    
        public static void main(String[] args) {
            Base base = new Derived();
            base.test();
        }
    }

      

    提升派生类中test方法的访问权限

    将Base类中test()的访问权限改为protect,将Derived类中test()的访问权限改为public,这时程序可以正确执行,说明可以在派生类中提升test()方法的可访问性。

    public class Base implements BaseIF {
        public void Access(){
            test();
        }
    
        protected void test(){
            System.out.println("test in Base");
        }
    }
    public class Derived extends Base {
        @Override
        public void test(){
            System.out.println("test in Derived");
        }
    }

    但有一点需要注意的是,如果Base中test()为private,那么在Derived中是看不到Base的test()的。这时Derived中如果也添加test()方法(无论访问权限是什么),都不属于重写Base的test()方法,Derived的test()方法只属于Derived类本身,而这时也无法实现多态。举例:

    public class Base implements BaseIF {
        public void Access(){
            test();
        }
    
        private void test(){
            System.out.println("test in Base");
        }
    }
    public class Derived extends Base {
        //@Override
        public void test(){
            System.out.println("test in Derived");
        }
    }
    public class Main {
    
        public static void main(String[] args) {
            BaseIF face = new Derived();
            face.Access();
        }
    }

    运行结果:

    test in Base

  • 相关阅读:
    r_action
    微内核 客户服务器模式 分布式
    机制与策略分离
    自顶向下设计
    swap
    专人写接口+模型,专人写业务逻辑---interface_model -- business logical
    14days laravel
    t
    不用print调试 xdebug ubuntu phpstorm 远程断点调试
    peewee sqlalchemy
  • 原文地址:https://www.cnblogs.com/canger/p/6277473.html
Copyright © 2011-2022 走看看