您的位置 首页 java

JAVA编程语言中受保护的访问修饰符protected分析

这个 protected 看似简单,但细分析起来让人头大,参考网上的一段教程,结合自己的分析做一下总结,仅供参考。

最关键的一句话: 被 protected 修饰的成员对于本包和其子类可见

然后是展开的解释:

  • 子类与基类在同一包中 :被声明为 protected 的变量、方法和构造器能被同一个包中的任何其他类访问;

  • 子类与基类不在同一包中 :那么在子类中,子类实例可以访问其从基类继承而来的 protected 方法,而不能访问基类实例的protected方法。

然后我们要知道,默认的 java 类如果没有显式继承一个类,那它默认继承的是java.lang.Object。

java.lang.Object中有一个clone()函数,是protected类型的。

然后我们开始对网上的一个教程进行分析。这个教程有一些错别字,但大概意思倒是正确的。

下面的分析流程按照固定的顺序,首先是包名,其次是调用函数所在的类名,最后是变量被调用的类名。

我们通过取出满足条件的包名及子类名( 子类名有继承顺序 )来进行判断。

我们的分析流程是机械化分析。


JAVA编程语言中受保护的访问修饰符protected分析

son1和son11的f()是在Father1中定义的,所以Father1所在的包p1和Father1的子类都对f()可见。

上图(1)(3)两处的代码位于包p1中,虽然Test1不是Father1的子类,但依然可见,所以编译成功。

上图(2)(4)两处的clone()其实是Father1继承的java.lang.Object中定义的,所以clone()是在java.lang.Object所在的包java.lang和java.lang.Object的子类(这个子类是Father1,Son1,Son11,按继承顺序写下就是Father1->Son1,Father1->Son11)中可见。显然,包p1不等于java.lang,而Test1也不是Father1或Son1或Son11,所以不满足任何一个条件,编译不通过。


JAVA编程语言中受保护的访问修饰符protected分析

上图(1)处的clone来自哪里呢?显然来自MyObject2中自己定义的clone(),那么该clone()对于所在的包p2和MyObject2的子类(Test2)是可见的。包p22不等于p2,第一个条件不满足,但是Test2是MyObject2的子类,这个条件满足,再往下,这个obj是MyObject2类,不是子类Test2,不满足,因此编译错误。

上图(2)处的tobj是来自Test2,虽然所在包不满足,但是Test2是子类满足第二个条件,再往下tobj所在的类仍然是Test2,因此编译成功。


JAVA编程语言中受保护的访问修饰符protected分析

上图(1)处的clone()最终是来自Test3继承的java.lang.Object类,所以clone()对于java.lang包及java.lang.Object的子类(按继承先后顺序写下即是Test3->MyObject3)可见。虽然包p33不等于java.lang,但是Test3满足子类的条件,再往下MyObject3满足是子类的条件,因此编译成功。


JAVA编程语言中受保护的访问修饰符protected分析

上图(1)处的clone()显然来自MyObject4中的自定义的clone(),因此这个clone()对于包p4及MyObject4的子类(此处无子类)可见。我们先看包p44,显然不等于p4,第一个条件不满足。然后我们看Test4,显然不在子类里(子类压根没有),所以下面不用再分析了,肯定编译失败。


JAVA编程语言中受保护的访问修饰符protected分析

上图(1)处的clone()显然来自MyObject5自定义的clone(),因此该clone()对于包p5及MyObject5的子类(此处无子类)可见。我们发现Test5其实就在子类p5中,所以第一个条件已经满足了,所以下面不用分析了,肯定编译成功。


JAVA编程语言中受保护的访问修饰符protected分析

上图(1)处的clone()来自Test6继承的java.lang.Object中的clone()函数,因此对于java.lang包及java.lang.Object的子类(此处按继承顺序写下即是Test6->MyObject6)可见。现在开始分析,我们发现Test6所在的包其实就是p6,不等于java.lang,第一个条件不满足,Test6满足子类的条件,因此通过,继续往下,obj对应的类MyObject6满足子类的要求,通过。因此该处编译成功。


JAVA编程语言中受保护的访问修饰符protected分析

上图(1)处的clone()显然是来自Test7默认继承的java.lang.Object类,因此对于java.lang包及java.lang.Object的子类(此处即是Test7,MyObject7)可见。现在开始分析,我们发现MyObject7所在的p7包名不等于java.lang,第一个条件不满足,然后我们看Myobject7这个类名满足是子类的条件,条件满足,最后我们分析下test变量所对应的类型Test7,我们发现Test7也在子类中,似乎应该是编译成功才对啊。

此处我们要注意 ,子类的继承有个顺序,上图中的顺序是Test7继承的java.lang.Object,而接着才是MyObject7继承的Test7,按顺序写下来就是(Test7->MyObject7)。所以上图的正确分析是,第一步分析包名,发现p7不等于java.lang,因此不满足,接着分析Myobject7,发现满足在子类中(此处先分析的MyObject7,因此Test7不能再分析了),接着再分析Test7,虽然在子类中,但是Test7在MyObject7的前面而且MyObject7先分析过了, 不能往前分析,所以其实Test7不存在子类中了,如果在后面(MyObject7->Test7)是可以的。因此编译错误。

其实该实例正规的理解是:包不同时,子类实例不能访问基类实例的protected方法。我们用上面的方法只是为了机械化判断。


上面的分析办法不是正规的分析和理解 ,但是对于你做题或者辅助理解是可以的。

打个比喻就像在你管辖的国家和地区有个人请求做一件事(该请求是被保护的,是protected形式,因此需要额外监督),你的职责就是判断这件事是否可以做。你首先就是找到这件事的最原始的发送命令方是哪个国家的谁发出的,然后判断这个命令的使用范围,进而得出你所管辖的国家及所在的地区及这个人是否可以执行这件事。

文章来源:智云一二三科技

文章标题:JAVA编程语言中受保护的访问修饰符protected分析

文章地址:https://www.zhihuclub.com/192821.shtml

关于作者: 智云科技

热门文章

网站地图