- 浏览: 1337847 次
- 性别:
- 来自: 湖南澧縣
文章分类
最新评论
-
虾米小尹:
不行啊!2.2-0.25=1.9500000000000002 ...
JavaScript浮点数运算 —— 精度问题 -
heluping000000:
引用String a= "abc",首先在 ...
String,到底创建了多少个对象? -
mack:
谢谢分享matcher.appendReplacement(s ...
string.replaceAll()中的特殊字符($ \)与matcher.appendReplacement -
wzt3309:
完全理解,比网上其他资料都要详细
String,到底创建了多少个对象? -
u014771876:
Java中十六进制转换 Integer.toHexString()
Java中的访问控制修饰符有四个级别,但属protected最复杂。如果问大家,protected修饰符作用,大家会说“在子类与同包中可以访问这个成员”,当然在自己类中也是可的,但你真的理解了吗?不信,先看看下面这些实例,看你是否也是这样想的(其中注释掉的是不能编译的,大家最好把这些代码放在eclipse中再看,不然你会晕的^_^):
package pk1.a; public class Base { protected int i = 1; protected void protect() { System.out.println("Base::protect"); } } package pk1.a; import pk1.b.Sub; public class SubSub extends Sub { void g() { Sub s = new SubSub(); //!! s.protect();//规则2.c.i System.out.println(s.i);//规则2.c.ii } } package pk1.b; import pk1.a.Base; public class Sub extends Base { private void prt() {} protected void protect() { System.out.println("Base::protect"); } void f() { //规则2.a this.protect(); this.i = 2; //规则2.b Base a2 = new Sub(); //!! a2.protect(); //!! System.out.println(a2.i); //规则1 Sub b = new Sub(); b.protect(); b.i = 1; b.prt(); } } package pk1.b; public class SubSub extends Sub { void g() { Sub s = new SubSub(); s.protect();//规则2.c.i //!! System.out.println(s.i);//规则2.c.ii } } package pk1.c; import pk1.a.Base; import pk1.b.Sub; public class SubSub extends Sub { void g() { this.protect();//规则2.a //规则2.b Base b = new SubSub(); //!! b.protect(); //!! System.out.println(b.i); //规则2.b Sub s = new SubSub(); //!! s.protect(); //!! System.out.println(s.i); } }
package pk2.a; public class Base { protected int i = 1; protected void protect() { System.out.println("Base::protect"); } } package pk2.a; import pk2.b.Sub; public class Other { void g() { //规则3.a Base b = new Sub(); b.protect(); System.out.println(b.i); //规则3.b.ii Sub s = new Sub(); s.protect(); System.out.println(s.i); } } package pk2.b; import pk2.a.Base; public class Other { void g() { //规则3.a Base b = new Sub(); //!! b.protect(); //!! System.out.println(b.i); //规则3.b.ii Sub s = new Sub(); //!! s.protect(); //!! System.out.println(s.i); } } package pk2.b; import pk2.a.Base; public class Sub extends Base {}
package pk3.a; import pk3.b.Sub; public class Base { protected int i = 1; protected void protect() { System.out.println("Base::protect"); } static protected int i_s = 1; static protected void protect_s() { System.out.println("Static:Base::protect"); } void f() { //!! Sub.i_s = 2; //规则3.b.i Sub.protect_s();//规则3.b.ii } } package pk3.a; import pk3.b.Sub; public class Other { void g() { Sub s = new Sub(); //!! s.protect();//规则3.b.i System.out.println(s.i);//规则3.b.ii } void f() { //!! Sub.i_s = 2; //规则3.b.i Sub.protect_s();//规则3.b.ii Base.i_s = 2;//规则3.a Base.protect_s();//规则3.a } } package pk3.b; import pk3.a.Base; public class Other { void f() { Sub.i_s = 2;//规则3.b.i //!! Sub.protect1();//规则3.b.ii //!! Base.i1 = 2;//规则3.a //!! Base.protect1();//规则3.a } } package pk3.b; import pk3.a.Base; public class Sub extends Base { protected void protect() { System.out.println("Base::protect"); } static protected int i_s = 2; void f() { /* * 在子类中可能通过子类类型或父类类型来来访问父类中protected静态 * 成员,而不管子类与父类是否在同一包中,或是子类重新定义了这些成员 * * 注,在父类或子类中访问时后面的规则不再适用 */ System.out.println(Sub.i_s);//2 Sub.protect_s(); System.out.println(Base.i_s);//1 Base.protect_s(); } }
如果你看到这里,想法与程序一致的话,说明你理解了,如果不理解,那看看我的理解吧:
定义规则前,我这里约定有三个类,一个是Base类,一个是Base类的子类Sub类,一个是Sub类的子类SubSub类,另一个是Other类且与Base、Sub、SubSub没有继承关系,并假设Base中有protected方法与属性,都叫YYY吧。
在理解protected规则:首先要搞清楚什么叫访问?这里在讲到的访问是有二种的:
一、就是在类中通过“XXX x = new XXX(); x.YYY;”的形式来访问(不妨叫此种形式为“外部访问”吧,此种访问形式除了可以应用到自己与子类中外,还可以应用在其他类中访问,其中XXX表示定义的类型,这里可为Base与Sub、SubSub,YYY为方法或属性);
二、就是this.YYY的形式来访问(不妨叫此种形式为“内部访问”吧,不过这种访问形式只能应用在在自己的类或是子类中)。
protected方法与属性可访问的地方有三个:
1. 在自己的类Base中:上面的“XXX x = new XXX(); x.YYY;”与“this.YYY”两种访问形式都可以访问的到自己定义的portected方法或属性;
2. 二是子类Sub、SubSub中,这要分三种访问方式:
a. 在Sub、SubSub 中的“this.YYY”内部访问形式:在此种方式形式下,不管是否重写或重新定义过父类Base中protected方法与属性,子类Sub、SubSub一定可以访问的。
b. 在Sub、SubSub 中“Base x = new XXX (); x.YYY;”外部访问形式:此种形式就不一定的能访问的到了,这要看父类Base与子类Sub、SubSub是否在同一包(注意,此时与是否重写或重新定义过这些protedted方法与属性没有关系);
c. 在SubSub 中“Sub x = new XXX (); x.YYY;” 外部访问形式:此种访问形式能否访问关键看Sub是否重写或重新定义过Base的属性与方法:
i. 如果重写或重新定义过,则看Sub与SubSub是否在同包中
ii. 如果没有,则看Base与SubSub是否在同包中
3. 在其他类Other中:此时只支持外部访问形式,不过到底是要求Other与Base同包还是要求Other与Sub同包,则要依你访问方式而定了:
a. 如果是通过父类引用“Base x = new XXX (); x.YYY;”形式来访问的,则要求Other与Base同包;
b. 如果是通过子类引用“Sub x = new Sub (); x.YYY;”形式来访问的,情况又会比较复杂了,此时关键是看子类Sub是否重写或重新定义过父类Base中的protected方法与属性:
i. 如果重写或重新定义过了,则要求Other与Sub同包即可;
ii. 如果没有重写或重新定义过了,则要求Other与Base同包即可;
另外,写到这里我想到了Object中的clone方法,为什么要求具有克隆能力的类要求实现Cloneable接口与clone方法呢:Object.clone()访问修饰符为protected,如果某个类没有重写此方法,则Object中的clone()方法除被自己与子类能调用方法外,其他不管与这个类在同一包还是不同包都是不可见的,因为未重写,还是属于Object中的方法,又Object在java.lang包中,与我们定义的包又不在java.lang包中,所以不能访问到(这也与你在在程序里定义了Object o = new Object();你还是不能在当前类中调用o.clone();一样),这也恰好符合上面 3.b.ii 这条规则。所以如果要能被不同包中的非子类克隆,则需重写Object.clone()并设置访问权限为public(如果重写后还是protected,则还是只能被同一包访问)。
以上这些就是我对protected限制的一种理解,肯定还有遗漏的地方,希望大家给我指出来,我来完善它。如果对你有帮助,请支持一下!
刚刚发现的一个小问题,一并附上《protected,这个错了吗?》
非常感谢大家,看了一下大家的理解,我上面的理解确实比较复杂,这正是因为把继承访问与非继承访问混在一起了就复杂了。其实这么理解就最简单了,还是以那句话,protected修饰的成员只允许子类与包访问!只不过子类可访问是指继承访问,即在子类的实例中直接访问继承过来的protected成员,而不是在子类中通过创建父类实例的方式来访问;而包访问就是指通过“XXX x = new XXX(); x.YYY;”的方式来访问,即通过实例的引用来访问,能不能访问就是看访问的代码所在的类是否与类XXX 在同一包中。但包访问要注意一点的是:如果XXX中只是继承了父类中的protected成员,而没有重写(方法)或重新定义(属性)这些成员,则能不能访问就要看当前访问的代码所在的类是否与类XXX的父类在同一包;另外如果类XXX重写与重新定义过这些protected成员,则就直接看访问代码所在的类与类XXX是否在同一包即可。
最后要注意的是静态的受保护成员比较特殊,因为protected static 成员即使被子类重写(严格的讲不叫重写)或重新定义后,还是会被继承下来,即在子类会有两份这样的static protected成员,只是他们的所属域(类)不同而已,所以在子类中可以通过父类的类型来访问所属于父的这些成员而不管子类与否与父类在同一包中,这与非静态的是不一样的。
补充:方法能重写,属性能重写吗
评论
对于编译器而言,它是不能区分多态的。因此在编译时,通过申明类型来决定是否可以访问。
这样理解是科学+简单地!
编译时和运行时理解了,就不纠结了!
Java 的protected包含了所有的default特性。
我的理解是 protected只是给与父类不同package的子类一个通过super.xxx()访问父类的方式
无聊
+1
无聊
<div class="quote_div">
<div class="quote_title">yssas 写道</div>
<div class="quote_div">protected本没有这么复杂,楼主把这个搞复杂了<br>有一个简单的办法——你把所有new换成一个工厂方法,这样:<br> XXX x=Factory.createXXX();<br>就可以很直观很明显地看出了。<br>ps:示例代码有错,请lz详查……</div>
<br><br>哪儿有错?请指示。</div>
<p><br>是我的结论轻率了,细看之后,发现至少原来认为有错的第一段代码是没有错误的。不过我想总结一个关于字段访问控制的假象算法:</p>
<p> </p>
<p>字段没有动态绑定且基于隐藏机制。访问字段时,自目标对象对象所声明的类型开始,沿继承体系向上,直到相应字段的定义位置,然后检查访问者权限</p>
<p> </p>
<p>对于方法的访问,直接视其声明类型就行了。根据Liskov替换原则,子类不可能降低父类的访问设置,这也就是我提出将new换成工厂方法的原因。</p>
<p> </p>
看完文字。。我发现我晕了,,,麻烦下次举例的时候来个正常字。。。
XXX YYY 然后我 zzz~ 了
嗯,提的好,不过知道如何修改,还请指示
有一个简单的办法——你把所有new换成一个工厂方法,这样:
XXX x=Factory.createXXX();
就可以很直观很明显地看出了。
ps:示例代码有错,请lz详查……
哪儿有错?请指示。
有一个简单的办法——你把所有new换成一个工厂方法,这样:
XXX x=Factory.createXXX();
就可以很直观很明显地看出了。
ps:示例代码有错,请lz详查……
看完文字。。我发现我晕了,,,麻烦下次举例的时候来个正常字。。。
XXX YYY 然后我 zzz~ 了
发表评论
-
Java正则表达式
2014-03-14 10:16 1766Java正则表达式详解 作者:jzj 文 ... -
类的初始化与清理
2013-06-24 22:20 1456初始化时内存清零 当创建一个对象时,首先将在堆上为这个对象分 ... -
protected,这个错了吗?
2013-06-24 22:17 1251这几天对protected修饰符有点迷糊,随便找同事要了一本 ... -
Java中BigDecimal的8种舍入模式
2013-06-21 18:42 2185java.math.BigDecimal不可变的、任意精度的 ... -
Tomcat性能参数设置
2010-12-27 15:35 34802默认参数不适合生产环境使用,因此需要修改一些参数 1、 ... -
Java 6 JVM参数选项大全
2010-12-14 11:16 1638http://kenwublog.com/docs/java6 ... -
对象的安全构造
2013-06-21 18:43 1546在构造期间,不要公布“this”引用 一种可以将数据争用引 ... -
Java断言(assert)—— 转
2010-06-20 10:36 12101一、概述 在C和C++语言中都有assert关键,表示断言。 ... -
eclipse调试
2010-06-04 00:11 8083eclipse远程调试 在eclipse3.4前,远程调试时 ... -
利用反射进行深层克隆
2010-05-05 21:02 3670最近在看《effective java ... -
类与类之间的几种关系
2010-05-03 13:49 2419类和类、类和接口、接 ... -
运行java
2010-05-03 13:47 1053用javac命令编译一个打包的类时,如果没有加参数" ... -
Java内存模型与volatile
2010-04-25 13:21 18796内存模型描述的是程序 ... -
中断线程
2010-04-24 21:19 8997中断线程 线程的thread.i ... -
java中的关键字、保留字、标示符
2010-04-07 23:48 3376关键字 Java的关键字对java的编译器有特殊的意义, ... -
Java中的浮点数剖析
2010-04-07 23:27 4723定点数表达法的缺点在于其形式过于僵硬,固定的小数点位置决定了固 ... -
线程间的同步与互斥
2010-03-23 21:29 2305线程间的同步(实指线程间的通信):一般来说,一个线程相对于另 ... -
UTF-16、UTF-16BE、UTF-16LE编码方式的区别
2010-03-23 21:20 9820import java.io.IOException; ... -
final、finally、finalize
2010-01-22 01:15 2429final关键字 先看看final关键字,它可以被用于以下几个 ... -
方法能重写,属性能重写吗?
2010-01-22 00:56 6973覆写是多态的一种表现,我们平时所说的覆写一般是针对方式来说,在 ...
相关推荐
`protected`是Java中四种访问权限之一,它在类的封装和继承中扮演着重要的角色。本篇文章将深入探讨`protected`关键字的含义、用法以及它在实际开发中的应用。 1. `protected`的含义: `protected`是一种中级访问...
综上所述,理解并合理使用`public`、`protected`和`private`对于编写清晰、安全且易于维护的代码至关重要。掌握这些访问修饰符的用法可以帮助开发者更好地设计类的结构,实现面向对象编程的原则。在实际开发中,应...
通过阅读《Protected Mode Software Architecture》这本书,读者可以全面理解保护模式的原理,学习如何设计和实现高效、安全的软件架构,这对于开发操作系统、驱动程序或者进行系统级编程是必不可少的基础知识。
而PassView则是一个由 NirSoft 开发的小巧实用工具,它能够帮助用户查看并提取Protected Storage中的密码信息。 Protected Storage PassView的主要功能有以下几点: 1. **密码恢复**:当用户忘记了保存在浏览器、...
《JEDEC JESD260:2021 Replay Protected Monotonic Counter (RPMC) for Serial Flash Devices》这份文档详细介绍了RPMC(重放保护单调计数器)技术在串行闪存设备中的应用。RPMC是一种重要的安全机制,主要用于防止...
《Wi-Fi CERTIFIED Protected Management Frame System Interoperability Test Plan》版本1.4是Wi-Fi Alliance发布的一份关于802.11w协议认证的重要文档。802.11w,也称为Management Frame Protection (MFP),是Wi-...
在这个深入理解中,我们将详细探讨`protected`关键字的含义、用法以及其在多态和继承中的行为。 首先,`protected`关键字的基本概念是它比默认(包级私有)权限更开放,但比`public`权限更受限。与`public`不同,`...
描述中的“Protected Storage PassViewHA_PSPV1.63_LRH.rar”指的是该工具的特定版本,即版本号为1.63,由LRH发布的汉化版(HA表示汉化,LRH可能是汉化者的标识)。RAR是一种常见的压缩文件格式,用于打包多个文件或...
### JAVA 访问修饰符及 protected 的几点被人忽略的致命要害 #### 一、概述 在 Java 中,访问控制修饰符用于...希望本文能够帮助您更好地理解和应用 `protected` 访问修饰符,从而写出更加健壮和优雅的 Java 代码。
Wi-Fi Protected Access(WPA)是无线网络领域中一种重要的安全标准,旨在提供更好的加密机制和数据完整性,保护用户在无线局域网(WLAN)中的通信安全。本篇文章将深入探讨WPA的工作原理、加密技术和数据完整性机制...
在理解和实施WPS时,还需要参考以下相关文档: - **WPA规范**:定义了Wi-Fi网络的安全框架。 - **IEEE 802.11标准**:规定了无线局域网的技术细节。 - **其他Wi-Fi Alliance文档**:包括认证指南和其他技术建议。 #...
WPS(Wi-Fi Protected Setup)是一种设计用于简化Wi-Fi设备安全设置流程的标准。它旨在简化WPA(Wi-Fi ...通过深入学习WPS协议的这些知识点,可以更好地理解和应用这一标准,以确保无线网络的便捷接入与安全性。
理解这些访问修饰符对于编写健壮且安全的Java代码至关重要。正确使用它们可以帮助我们设计出具有良好封装性和扩展性的类结构。在实际开发中,根据需求选择合适的访问权限,可以有效防止不必要的数据暴露,提高代码的...
知识点: 1. Protected Interoperable File Format(PIFF)的定义和重要性 PIFF(Protected Interoperable File Format...理解这些内容对于开发兼容PIFF的设备或软件、或在遵守专利政策的前提下实现PIFF格式至关重要。
通过创建不同包内的类和子类,并观察它们如何访问`protected`成员,可以直观地理解访问控制的规则。例如,可以创建一个父类`A`,其中包含一个`protected`变量`x`,然后在不同的包内创建子类`B`和`C`,观察它们能否...
在这个特定的讨论中,焦点集中在`protected`关键字和默认(default)访问控制修饰符上,特别是在跨包继承的情景下。 `protected`访问修饰符允许子类和同一个包内的类访问其成员。然而,这里有两个关键点经常被忽视...
总的来说,"protected_ncverilog.rar_DRAM_ddr4_ddr4模型_ncverilog_silkei2"提供的资源是DDR4 DRAM设计和验证的一个宝贵工具,利用NCVerilog仿真器,用户可以深入研究DDR4内存系统的功能和行为,为硬件设计和系统级...