博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入理解 Java 中 protected 修饰符
阅读量:6227 次
发布时间:2019-06-21

本文共 3238 字,大约阅读时间需要 10 分钟。

看似简单的东西可以引出很多问题,学习过程中很多概念我们都只是「好像了解」、「貌似是这样」、「应该没问题」, 其实缺乏的是仔细思考, 对自己少问了几个「为什么」。

在 Java 中, 访问权限修饰符属于最最基础的知识, protected 修饰符只是其中一个, 如果你要问为什么不拿 public、default、private 来深究呢? 那么看完这篇文章你会知道为何 protected 更值得深入️思考。

在 《Thinking in Java》 中,protected 的名称是「继承访问权限」,这也就是我们记忆中的 protected:protected 必须要有继承关系才能够访问。 所以你以为你懂了, 可是你真的理解了这句话吗?

先思考几个问题:

  1. 同一个包中, 子类对象能访问父类的 protected 方法吗?

  2. 不同包下, 在子类中创建该子类对象能访问父类的 protected 方法吗?

  3. 不同包下, 在子类中创建父类对象能访问父类的 protected 方法吗?

  4. 不同包下, 在子类中创建另一个子类的对象能访问公共父类的 protected 方法吗?

  5. 父类 protected 方法加上 static 修饰符又会如何呢?

《Thinking in Java》中有一句话:「protected 也提供包访问权限, 也就是说,相同包内的其他类可以访问 protected元素」, 其实就是 protected 修饰符包含了 default 默认修饰符的权限, 所以第 1 个问题你已经知道答案了, 在同一个包中, 普通类或者子类都可以访问基类的 protected 方法。

父类为非静态 protected 修饰类

package com.protectedaccess.parentpackage;public class Parent {    protected String protect = "protect field";    protected void getMessage(){        System.out.println("i am parent");    }}复制代码

不同包下,在子类中通过父类引用不可以访问其 protected 方法

无论是创建 Parent 对象还是通过多态创建 Son1 对象, 只要 Parent 引用, 则不可访问, 编译器会提示错误。

package com.protectedaccess.parentpackage.sonpackage1;import com.protectedaccess.parentpackage.Parent;public class Son1 extends Parent{    public static void main(String[] args) {        Parent parent1 = new Parent();        // parent1.getMessage();   错误        Parent parent2 = new Son1();        // parent2.getMessage();  错误    }}复制代码

不同包下,在子类中通过该子类引用可以访问其 protected 方法

子类中实际上把父类的方法继承下来了, 可以通过该子类对象访问, 也可以在子类方法中直接访问, 还可以通过 super 关键字调用父类中的该方法。

package com.protectedaccess.parentpackage.sonpackage1;import com.protectedaccess.parentpackage.Parent;public class Son1 extends Parent{    public static void main(String[] args) {        Son1 son1 = new Son1();        son1.getMessage(); // 输出:i am parent,    }    private void message(){        getMessage();  // 如果子类重写了该方法, 则输出重写方法中的内容        super.getMessage(); // 输出父类该方法中的内容    }}复制代码

不同包下,在子类中不能通过另一个子类引用访问共同基类的 protected 方法

package com.protectedaccess.parentpackage.sonpackage2;import com.protectedaccess.parentpackage.Parent;public class Son2 extends Parent {}复制代码

注意是 Son2 是另一个子类, 在 Son1 中创建 Son2 的对象是无法访问父类的 protected 方法的

package com.protectedaccess.parentpackage.sonpackage1;import com.protectedaccess.parentpackage.Parent;import com.protectedaccess.parentpackage.sonpackage2.Son2;public class Son1 extends Parent{    public static void main(String[] args) {        Son2 son2 = new Son2();        // son2.getMessage(); 错误    }}复制代码

父类为静态 protected 修饰类

对于protected的静态变量, 在子类中可以直接访问, 在不同包的非子类中则不可访问

package com.protectedaccess.parentpackage;public class Parent {    protected String protect = "protect field";    protected static void getMessage(){        System.out.println("i am parent");    }}复制代码

静态方法直接通过类名访问

无论是否同一个包,在子类中均可直接访问

package com.protectedaccess.parentpackage.sonpackage1;import com.protectedaccess.parentpackage.Parent;public class Son3 extends Parent{    public static void main(String[] args) {        Parent.getMessage(); // 输出: i am parent    }}复制代码

在不同包下,非子类不可访问

package com.protectedaccess.parentpackage.sonpackage1;import com.protectedaccess.parentpackage.Parent;public class Son4{    public static void main(String[] args) {       // Parent.getMessage(); 错误    }}复制代码

看到这里你应该知道有多少种情况了, 针对不同的情况都可能出现意外的结果, 所以还是得多实践, 仅仅在书上看一遍 protected 修饰符的作用是无法真正发现它的微妙。

转载地址:http://wsnna.baihongyu.com/

你可能感兴趣的文章
批处理学习笔记2 - 编写批处理的for循环
查看>>
【web前端面试题整理07】我不理解表现与数据分离。。。
查看>>
C++一些注意点之转换操作符
查看>>
以JTextPanel为例Swing的鼠标事件详解
查看>>
【转】python中的lambda函数
查看>>
HashSet中实现不插入重复的元素
查看>>
atitit.破解 拦截 绕过 网站 手机 短信 验证码 之自动获取手机短信方式 attilax 总结...
查看>>
mongodb用户授权
查看>>
操作系统学习基本概念汇总
查看>>
RESTful架构详解
查看>>
linux环境下安装sphinx中文支持分词搜索(coreseek+mmseg)
查看>>
用户IP地址的三个属性的区别(HTTP_X_FORWARDED_FOR,HTTP_VIA,REM_addr
查看>>
编写高质量代码:改善Java程序的151个建议(第1章:JAVA开发中通用的方法和准则___建议11~15)...
查看>>
华为OJ平台试题 ——数组:整形数组合并
查看>>
ORA-01410: 无效的 ROWID
查看>>
【Spark】Spark Streaming + Kafka direct 的 offset 存入Zookeeper并重用
查看>>
golang web开发获取get、post、cookie参数
查看>>
一个JAVA程序员经常访问的网站
查看>>
漫画:鉴权与安全访问控制的技术血脉
查看>>
C# 3.0入门系列-目录导航
查看>>