




已阅读5页,还剩4页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
JAVA面试题解惑系列(三)变量(属性)的覆盖我们来看看这么一道题: Java代码 class ParentClass public int i = 10; public class SubClass extends ParentClass public int i = 30; public static void main(String args) ParentClass parentClass = new SubClass(); SubClass subClass = new SubClass(); System.out.println(parentClass.i + subClass.i); /自加System.out.println(parentClass.i);/10System.out.println(subClass.i);/30 控制台的输出结果是多少呢?20?40?还是60? 变量,或者叫做类的属性,在继承的情况下,如果父类和子类存在同名的变量会出现什么情况呢?这就是这道题要考查的知识点变量(属性)的覆盖。 这个问题虽然简单,但是情况却比较复杂。因为我们不仅要考虑变量、静态变量和常量三种情况,还要考虑private、friendly(即不加访问修饰符)、protected和public四种访问权限下对属性的不同影响。 我们先从普通变量说起。依照我们的惯例,先来看一段代码: Java代码 class ParentClass private String privateField = 父类变量-private; /* friendly */String friendlyField = 父类变量-friendly; protected String protectedField = 父类变量-protected; public String publicField = 父类变量-public; / private的变量无法直接访问,因此我们给他增加了一个访问方法 public String getPrivateFieldValue() return privateField; public class SubClass extends ParentClass private String privateField = 子类变量-private; /* friendly */String friendlyField = 子类变量-friendly; protected String protectedField = 子类变量-protected; public String publicField = 子类变量-public; / private的变量无法直接访问,因此我们给他增加了一个访问方法 public String getPrivateFieldValue() return privateField; public static void main(String args) / 为了便于查阅,我们统一按照private、friendly、protected、public的顺序 / 输出下列三种情况中变量的值 / ParentClass类型,ParentClass对象 ParentClass parentClass = new ParentClass(); System.out.println(ParentClass parentClass = new ParentClass();); System.out.println(parentClass.getPrivateFieldValue(); /父类变量-private System.out.println(parentClass.friendlyField); /父类变量-friendly System.out.println(parentCtectedField);/ 父类变量-protected System.out.println(parentClass.publicField); /父类变量-public System.out.println(); / ParentClass类型,SubClass对象 (子转父) ParentClass subClass = new SubClass(); System.out.println(ParentClass subClass = new SubClass();); System.out.println(subClass.getPrivateFieldValue(); /调用了子类的方法(方法覆盖),子类变量-private System.out.println(subClass.friendlyField); /父类变量-friendly System.out.println(subCtectedField);/ 父类变量-protected System.out.println(subClass.publicField); /父类变量-public System.out.println(); / SubClass类型,SubClass对象 SubClass subClazz = new SubClass(); System.out.println(SubClass subClazz = new SubClass();); System.out.println(subClazz.getPrivateFieldValue(); /子类变量-private System.out.println(subClazz.friendlyField); /子类变量-friendly System.out.println(subCtectedField); /子类变量-protected System.out.println(subClazz.publicField); /子类变量-public 这段代码的运行结果如下: 1、ParentClass parentClass = new ParentClass(); 2、父类变量-private 3、父类变量-friendly 4、父类变量-protected 5、父类变量-public 6、7、ParentClass subClass = new SubClass(); 8、子类变量-private 9、父类变量-friendly 10、父类变量-protected 11、父类变量-public 12、13、SubClass subClazz = new SubClass(); 14、子类变量-private 15、子类变量-friendly 16、子类变量-protected 17、子类变量-public 从上面的结果中可以看出,private的变量与其它三种访问权限变量的不同,这是由于方法的重写(override)而引起的。关于重写知识的回顾留给以后的章节,这里我们来看一下其它三种访问权限下变量的覆盖情况。 子类型的对象,可以覆盖父类属性。父类型的对象,构造方法是子类的(子转父)不能覆盖属性,但子类同名实例方法被覆盖,同名静态方法不被覆盖,而子类方法可以直接访问子类属性,父类方法只能访问父类属性,子类方法可以访问子类属性和父类属性(当然得有权限)。由于private变量的特殊性,在接下来的实验中我们都把它排除在外,不予考虑。 由于上面的例子已经说明了,当变量类型是父类(ParentClass)时,不管我们创建的对象是父类(ParentClass)的还是子类(SubClass)的,都不存在属性覆盖的问题,因此接下来我们也只考虑变量类型和创建对象都是子类(SubClass)的情况。 Java代码 class ParentClass /* friendly */String field = 父类变量; public class SubClass extends ParentClass protected String field = 子类变量; public static void main(String args) SubClass subClass = new SubClass(); System.out.println(subClass.field); /子类变量 运行结果: 1、子类变量 Java代码 class ParentClass public String field = 父类变量; public class SubClass extends ParentClass protected String field = 子类变量; public static void main(String args) SubClass subClass = new SubClass(); System.out.println(subClass.field); 运行结果: 1、子类变量 上面两段不同的代码,输出结果确是相同的。事实上,我们可以将父类和子类属性前的访问修饰符在friendly、protected和public之间任意切换,得到的结果都是相同的。也就是说访问修饰符并不影响属性的覆盖,关于这一点大家可以自行编写测试代码验证。 对于静态变量和常量又会怎样呢?我们继续来看: Java代码 class ParentClass public static String staticField = 父类静态变量; public final String finalField = 父类常量; public static final String staticFinalField = 父类静态常量; public class SubClass extends ParentClass public static String staticField = 子类静态变量; public final String finalField = 子类常量; public static final String staticFinalField = 子类静态常量; public static void main(String args) SubClass subClass = new SubClass(); System.out.println(SubClass.staticField); /子类静态变量 System.out.println(subClass.finalField); /子类常量 System.out.println(SubClass.staticFinalField); /子类静态常量 运行结果如下: 1、子类静态变量 2、子类常量 3、子类静态常量 虽然上面的结果中包含“子类静态变量”和“子类静态常量”,但这并不表示父类的“静态变量”和“静态常量”可以被子类覆盖,因为它们都是属于类,而不属于对象。 上面的例子中,我们一直用对象来对变量(属性)的覆盖做测试,如果是基本类型的变量,结果是否会相同呢?答案是肯定的,这里我们就不再一一举例说明了。 *我们再回到篇首的那道题,我想大家都已经知道答案了,输出结果应该是40。这篇文章给出了很好的解疑方法,我也是跟着他来。下面我的文章将讲到:java中成员变量和方法的覆盖问题 对那篇文章中的提到的变量覆盖,我不同意。因此,在这里首先提出我的观点: 1、(子转父)同名实例方法被覆盖,同名静态方法不被覆盖,我们先看这段程序代码: class ParentMethord / 静态方法 static void getClassName() System.out.println(static: +ParentMethord.class.getName(); / 实例方法 void getName() System.out.println(ParentMethord.class.getName(); public class SubMethord extends ParentMethord / 重写父类静态方法 static void getClassName() System.out.println(static: +SubMethord.class.getName(); / 重写父类实例方法 void getName() System.out.println(SubMethord.class.getName(); public static void main(String args) ParentMethord parent= new SubMethord(); /子转父SubMethord sub=(SubMethord)parent; parent.getClassName(); / 静态方法调用的仍然是父类的方法 parent.getName(); / 实例方法调用的是子类的方法System.out.println();sub.getClassName(); / 子类中调用的当然是子类的方法 sub.getName(); 运行的结果为:static: ParentMethordSubMethordstatic: SubMethordSubMethord从这里可以看出当把一个子类对象自动转型为父类对象(ParentMethord parent= new SubMethord(); )时,同名静态的方法只是被隐藏起来了,转型为父类后仍然可以调用;而同名实例方法是被覆盖,转型后调用的也是子类的方法,即方法的重写。2、同名成员变量均被隐藏下面来讨论这一点。这里所说的成员变量包括静态成员变量和实例成员变量,(包括final型的),当然均是指父类中对子类可见的变量。看代码:class Parentstatic String staticStr=父类静态变量;String str=父类实例变量;public class SubVariable extends Parentstatic String staticStr=子类静态变量;String str=子类实例变量;public static void main(String args)Parent parent= new SubVariable();SubVariable sub = (SubVariable)parent;System.out.println(parent.staticStr);System.out.println(parent.str);System.out.println();System.out.println(sub.staticStr);System.out.println(sub.str);运行结果为:父类静态变量父类实例变量子类静态变量子类实例变量由此可见成员变量均只是被隐藏,当自动转型为父类时,仍然可见。final型的也一样,这里就不再讨论。插入:在这里还想扯到一个话题,以前总听胡总告诫:不要直接用点来访问对象成员变量,而用方法来访问。从这里有所体会。因为子类对象和父类对象成员变量如果出现重名,当把一个子类对象当作父类
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 校外小饭桌安全知识培训课件
- 校园超市消防知识培训总结课件
- 销售会计试题及答案
- 斜视护理试题及答案
- 北京预测培训基础知识课件
- 小学数学毕业考试题及答案
- 亲子母女测试题及答案
- 退休专家面试题及答案
- 幼儿法语试题及答案
- 空间向量试题及答案
- 铁道概论(第八版)佟立本主编
- 卫生院家庭医生签约服务考核表
- 智慧零碳园区解决方案
- 护士长夜查房记录表
- 重症患者的容量管理
- 长江三峡水利枢纽施工方案
- 中西医执业医师-综合笔试-中西医结合外科学-第二十三单元泌尿与男性生殖系统疾病
- 高中化学第一课课件高一上学期化学人教版
- 老服务伦理与礼仪讲课文档
- ERP项目实施进度计划表
- DB61T1730-2023公路路面煤矸石基层施工技术规范
评论
0/150
提交评论