tij中的习题:
class BaseWithPrint {
public BaseWithPrint() {
p.println("BaseWithPrint()");
print();
}
public void print() {
System.out.println("BaseWithPrint.print");
}
} class DerivedWithPrint extends BaseWithPrint {
int i = 47;
public DerivedWithPrint() {
p.println("DerivedWithPrint()");
}
public void print() {
System.out.println("i = " + i);
}
}public class GetFile {
public static void main( String args[] ){
DerivedWithPrint dp = new DerivedWithPrint();
dp.print();
}
}
输出结果如下:
在父类构造函数BaseWithPrint()中调用print(),既然是在父类的构造函数里,那么子类自然还没有构造,其成员函数按说也应该是不存在的呀!可是为什么这时可以调用子类的print()呢?
小弟初学java,问得可能比较幼稚,哪位前辈指点一下吧!
class BaseWithPrint {
public BaseWithPrint() {
p.println("BaseWithPrint()");
print();
}
public void print() {
System.out.println("BaseWithPrint.print");
}
} class DerivedWithPrint extends BaseWithPrint {
int i = 47;
public DerivedWithPrint() {
p.println("DerivedWithPrint()");
}
public void print() {
System.out.println("i = " + i);
}
}public class GetFile {
public static void main( String args[] ){
DerivedWithPrint dp = new DerivedWithPrint();
dp.print();
}
}
输出结果如下:
在父类构造函数BaseWithPrint()中调用print(),既然是在父类的构造函数里,那么子类自然还没有构造,其成员函数按说也应该是不存在的呀!可是为什么这时可以调用子类的print()呢?
小弟初学java,问得可能比较幼稚,哪位前辈指点一下吧!
解决方案 »
- 如何扩展Java的JTextField使之具有JCombox的选择功能,自动查询和完成功能。就像google搜索那样输入一个关键字就自动查询与关键字相关的内容
- 求救 :接口和抽象类
- 表单提交
- 急求达人!在JAVA应用程序中能不能调用VBS写的代码段,比如我要用我点一个按钮 触发一段打印一个EXCEL表格的VBS代码 ,在线等达人回复!
- 怎样显示ftp服务器端的文件目录啊,苦求………………!!
- 有没有一种办法可以返回定义的变量名称!
- 为什么我写的applet程序无法在没装java runtime的浏览器上运行,急
- 一个算法100分
- 真郁闷.昨天打赌输了.德国1:1平荷兰了..有段代码请大侠帮忙看一下.
- 微软的Java VM 和 Sun的 Java Runtime Enviroment有什么区别?
- 你有能力写一个中文时间解析器吗?
- 如何将java保存为utf8编码?
i = 0
DerivedWithPrint()
i = 47"i=47"没什么说的,我奇怪的是"i=0",此时DerivedWithPrint还没有被构造,Print()又不是Static型的,为什么就可以调用了呢?就好比一个对象还没有构造,如何能调用其成员呢?
方法也可以是primitive的?
类加载时不是首先初始化static的成员吗?
如果加载后成员函数就存在了(而与是否有这个类的实例无关),那么static的方法和non-static的方法有什么区别呢?
//JVM检查到DerivedWithPrint有父类BaseWithPrint,于是将其一齐载入
//现在开始初始化,首先为成员变量分配空间,如果是基本数据类型将其初始化,因此这里i被初始化为0
//现在开始执行构造函数,首先执行父类构造函数 BaseWithPrint(),打印BaseWithPrint()
然后是print(),由于这时候new的对象是DerivedWithPrint,因此调用DerivedWithPrint overwrite的print方法 ,打印i = 0
//接下来是DerivedWithPrint类自己的构造函数,成员变量赋初值 ,i被赋为47,然后是DerivedWithPrint(){}中的方法,打印DerivedWithPrint() i = 47
a +----+ -+---+-
| |
| | A
| |
b +----+ -+- C
| |
| | B
| |
c +----+ -+---+-我先用这个图表示类及其子类在内存中的逻辑概念上的分布。
其中:
1) 图形中的方框表示类在内存中的存储范围。
2) A表示从a点到b点的内存区
3) B表示从b点到c点的内存区
4) C表示从a点到c点的内存区现在有一个类SuperClass及其子类SubClass被加载到内存。其中SuperClass加载于内存区A,那么SubClass占用哪一部分内存呢?正确答案是C而不是B。二,从代码角度观察
对于继承,我们首先应该这样理解,代码中使用继承,只是为了减少代码量(那位,先把砖头放下),而不管父类还是子类,都是相对独立的类。当一个子类继承自其父类时,从代码角度,就是把其父类的代码重写一遍,然后再加上额外的代码,从而,成其子类。其实,这一工作是编译器完成的,当然也不是重写代码,但是我们可以这么直观的理解。我按照这种思路改造你的DerivedWithPrint,得到下面的代码:// 注意,去掉了extends
class DerivedWithPrint {
int i = 47;
public DerivedWithPrint() { //来自BaseWithPrint
p.println("BaseWithPrint()");
print(); // 本地
p.println("DerivedWithPrint()");
} public void print() {
System.out.println("i = " + i);
}
}这就是DerivedWithPrint类在运行时刻应该执行的命令及顺序。因为原来的DerivedWithPrint中也有print方法,所以覆盖了其父类的print方法。上述过程好像叫做类的扁平化。注意,如果原DerivedWithPrint的print方法中有super.print()字样,那么扁平化之后的print方法应该这样: public void print() {
System.out.println("BaseWithPrint.print");
System.out.println("i = " + i);
}三,应该清楚了吧?
既然成员方法在内存中只有一份拷贝,那静态的方法和非静态的方法有什么区别呢?仅仅是在形式上静态方法可以由类调用而非静态方法不可以吗?