class Parent{ int x=10; public Parent(){ add(2); } void add(int y){ x+=y; } } class Child extends Parent{ int x=9; void add(int y){ x+=y; } public static void main(String[] args){ Parent p=new Child(); System.out.println(p.x); } }
问输出结果是什么?
答案应该是10。
要理解结果为什么是10,需要首先明白下面的知识:
(1)方法和变量在继承时的隐藏与覆盖
隐藏:若B隐藏了A的变量或方法,那么B不能访问A被隐藏的变量或方法,但将B转换成A后可以访问A被隐藏的变量或者方法。
覆盖:若B覆盖了A的变量或者方法,那么不仅B不能访问A被覆盖的变量或者方法,将B转换成A后同样不能访问A被覆盖的变量或者方法。
(2)Java中变量与方法在继承中的隐藏与覆盖规则:
一、父类的实例变量和类变量能被子类的同名变量隐藏。
二、父类的静态方法被子类的同名静态方法隐藏,父类的实例方法被子类的同名实例方法覆盖。
三、不能用子类的静态方法隐藏父类的实例方法,也不能用子类的实例方法覆盖父类的静态方法,否则编译器会异常。
四、用final关键字修饰的最终方法不能被覆盖。
五、变量只能被隐藏不会被覆盖,子类的实例变量可以隐藏父类的类变量,子类的类变量也可以隐藏父类的实例变量。
在上面的试题中,子类Child的实例方法add(int y)覆盖了父类Parent的实例方法add(int y),而子类的实例变量x则是隐藏了父类的实例变量x。
Child对象的初始化过程是:
首先为父类的实例变量x分配内存空间,因为在定义变量x时为它赋了值(int x=10),所以会同时将这个值赋给x。
其次调用父类的无参构造函数,Parent的构造函数中做的唯一的事情就是调用了add(2);
第三、由于子类的add(int y)方法覆盖了父类的方法,所以add(2)实际调用的是子类的方法,在子类的add方法中做了如下操作x+=j;在这里由于子类的实例变量x隐藏了父类 的实例变量x,所以这条语句是针对子类本身的,但是这时还没有为子类的实力变量x分配空间,它的默认值是0,加2之后是2。
第四、父类初始化完毕后接着初始化子类,为子类的x分配内存空间并将它赋值为9,之前的add(2)操作白瞎了。
再次注意Parent p=new Child();这条语句,它是用父类的引用指向子类的对象,而前面已经说过变量只会被隐藏不会被覆盖,所以这时的p.x值应该是父类的10,而不是子类的9;
如果将输出语句换成下面的语句结果就是9了:
System.out..println(((Child)p).x); //首先将p转换成Child类型
原文:http://www.cnblogs.com/binjoo/articles/1585342.html
发表评论
-
Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask等
2011-09-30 16:08 1386方法一:(java习惯,在android不推荐使用) 刚刚开始 ... -
Android自定义对话框
2011-05-06 19:01 5742Android给我们提供了 AlertDialog类,使我们可 ... -
如何在android应用中添加项目符号
2011-05-05 11:28 3276如何给TextView控件中添加项目符号呢? ul/li/o ... -
如何阻止app_name在标题栏中闪现
2011-05-05 10:58 1737常见自定义titlebar的方 ... -
关于横竖屏切换activity重启的问题
2011-03-03 10:24 1374摘自:http://nwhy.org/android-conf ... -
android系统图标大全
2011-03-01 13:38 1668http://since2006.com/android/2. ... -
在WebView中调用拨号键
2011-03-01 13:18 1603原文:http://blog.sina.com.cn/s/bl ... -
自定义软键盘的Enter键
2011-01-11 20:05 3069我们在用新浪微博的登录注册时,会发现当鼠标放在第一个EditT ... -
一些标准操作所需的时间量
2011-01-10 21:52 988android应用中一些基本操作所需的时间量如下: 操作 ... -
对java编程应注意的基本优化
2011-01-10 20:04 1006摘自android应用开发解密一书中。 [1] 尽量指定 ... -
android系统部分广播
2010-12-27 16:23 2955转自:http://ming-fanglin.iteye.co ... -
android模拟器常用功能对应的快捷键列表
2010-12-13 10:57 1147有时候我们在使用Android模拟器时为了操作快速,我们总想使 ... -
谷歌宣布两周内推出新版Android Market
2010-12-12 23:13 824原文摘自新浪新闻,http://tech.sina.com.c ... -
最近在翻译国外一本新书 The Android Developer's Cookbook: Building Applications with the敬请关注
2010-12-12 11:57 1192最近在翻译国外一本新书 The Android Develop ... -
在模拟器上安装apk程序安装包
2010-12-12 11:33 1109在Android 模拟器上安装程序安装包apk,可以通过adb ... -
为Android添加第三方的jar包
2010-12-11 15:40 3036如果要给Android程序添加第三方的jar包,我们可以点击项 ... -
Android出现Could not find ***.apk!错误
2010-12-11 15:33 2035如果Android程序运行时出现Could not find ... -
使用ScrollView应注意的基本设置
2010-12-03 10:36 2446有时候我们在布局文件中需要使用Scrollview组件,使用时 ... -
如何为一个组件的同一属性同时声明两个值
2010-12-01 19:39 935在android开发中有时候我们可能像给一个组件声明两个位置属 ... -
虚拟机sdcard文件的删除
2010-11-22 10:51 1718adb remount adb shell cd sdcard ...
相关推荐
2. **构造器与初始化**:子类对象在创建时会先调用父类的构造器,确保父类的状态得到正确初始化,然后执行子类自己的构造逻辑。 3. **变量隐藏**:如果子类和父类有同名的实例变量,子类变量会“隐藏”父类变量。...
java 静态_非静态 字段_方法_代码块 子类父类构造_初始化顺序! 三个class 让你清清楚楚 第一个class java代码如下: package initialOrder; class Parent { // 静态变量 public static String p_StaticField...
综上所述,程序执行顺序的基本原则是:首先初始化并执行父类的构造器、静态和实例初始化块,然后执行子类的构造器、实例初始化块。最后,当通过子类对象调用方法时,优先执行子类覆盖的方法。理解这一顺序对于编写可...
在Java中,继承是面向对象编程的核心特征之一,它允许我们创建一个新类(子类)基于一个已经存在的类(父类或超类)的结构。这样可以复用现有类的代码,并可添加或覆盖特性来形成新的类。本文将通过具体的代码范例,...
这对于初始化父类的状态非常有用。 - **追溯父类**:`super`不仅可以用于直接父类,还可以追溯到更远的祖先类。 **2. 调用父类构造器的语法** 在子类的构造方法中,可以使用以下语法调用父类的构造方法: ```java...
3. **父类静态成员变量及初始化块**:如果当前类继承自另一个类,则父类的静态成员变量和静态初始化块会在子类之前被初始化。 4. **实例成员变量的默认初始化**:创建对象时,默认情况下,实例成员变量会被初始化为...
5. **子类的非静态实例初始化**:现在,所有父类的初始化都已经完成,`Cartoon`的构造器可以安全地初始化自己的实例变量。在这个例子中,没有显示的实例变量初始化,但如果有,它们将在此阶段进行。 6. **构造器...
- **显示调用**:通过初始化列表`BaseClass(param)`在子类构造函数中显式调用基类的特定构造函数。 构造原则: - 若子类没有定义构造函数,将调用父类的无参数构造函数。 - 子类定义了构造函数时,会先执行父类...
这是Java语言规范所规定的,确保在子类访问父类的静态或非静态成员时,父类的初始化已经完成。 在实际开发中,理解这个初始化顺序是非常重要的,尤其是在设计复杂的类结构或者涉及单例模式、线程安全初始化等场景时...
1. **静态初始化**:首先,执行父类的静态初始化块,然后执行子类的静态初始化块。静态初始化块用于初始化类级别的静态变量,它们只在类加载时执行一次。 2. **成员变量初始化**:接下来,初始化父类的非静态成员...
标题“javase子类父类继承关系图解”指的是对这一概念的可视化展示,帮助初学者更好地理解Java中的继承机制。 Java成员初始化顺序对于理解和正确使用继承至关重要。当创建一个子类对象时,其内存加载顺序遵循以下...
如果一个类是从另一个类继承的,子类的初始化会先调用父类的构造函数,确保父类的状态正确。然后,子类的实例初始化块和构造函数将依次执行。 7. **多线程环境下的初始化**: 如果多个线程同时尝试初始化同一个类...
- 在父类初始化完成后,JVM开始处理子类的初始化。子类的非静态变量、初始化块和构造器会被执行。在这个例子中,子类的"SubClass--变量"、"SubClass--初始化块"和"SubClass--构造器"会在子类构造器内部被执行。 4....
子类可以通过`super`关键字调用父类的构造函数,确保初始化时父类的属性得到正确的设置。 总结一下,子类调用抽象父类涉及到以下主要知识点: 1. **抽象类**:不能被实例化,含有抽象方法。 2. **抽象方法**:只有...
- **子类非静态初始化**:在父类初始化完成后,继续进行子类的实例初始化,包括子类的非静态初始化块和子类的非静态属性。`Son`类的非静态属性`b4`、非静态块以及`b5`的初始化按顺序进行,然后调用子类构造器`Test...
一旦父类初始化完成,才会开始子类的初始化。 特别要注意的是,在子类的初始化过程中,子类的静态变量和静态初始化块会在父类的变量、初始化块、构造器之前就被初始化。也就是说,在父类完全初始化完毕之前,子类的...
2. **非静态成员和非静态初始化块**:接着,会先初始化父类的非静态变量和执行父类的非静态初始化块,然后才是子类的相应部分。"父类 --变量" 和 "子类 --变量" 在这里被初始化,接着执行各自的初始化块。 3. **...
6. **类初始化与类加载器**: - 类的初始化是由对应的类加载器触发的,当且仅当以下条件之一满足时: - 遇到new关键字实例化对象; - 遇到静态字段(非final)并对其进行访问; - 遇到静态方法的调用; - 使用...