首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

子类覆盖父类的方法与属性后,把子类强制转化为父类类型,为什么这时方法体是子类的,而属性却是父类的呢?解决思路

2012-05-29 
子类覆盖父类的方法与属性后,把子类强制转化为父类类型,为什么这时方法体是子类的,而属性却是父类的呢?子

子类覆盖父类的方法与属性后,把子类强制转化为父类类型,为什么这时方法体是子类的,而属性却是父类的呢?
子类覆盖父类的方法与属性后,把子类强制转化为父类类型,为什么这时方法体是子类的,而属性却是父类的呢?
有如下代码可证(呵呵,透露一下,是IBM的面试题,至今我还未解开这个迷,请高手多多指教,不才感激不尽!):

Java code
public class FatherClild {    public static void main(String[] are) {        Child c = new Child();        Parent p = c;        System.out.println(p.ParentVar);        System.out.println(p.ParentStaticVar);        System.out.println(p.ParentStaticStr);        System.out.println(c.ParentVar);        System.out.println(c.ParentStaticVar);        System.out.println(c.ParentStaticStr);        p.parentMethod();        p.parentStaticMethod();        c.parentMethod();        c.parentStaticMethod();    }}class Child extends Parent {    public int ParentVar = 15;    public static int ParentStaticVar = 14;        //public static String ParentStaticStr = "child";        static {        System.out.println("this is a Child static block");    }    public Child() {        System.out.println("this is a Child construct");    }    public void parentMethod() {        System.out.println("this is a Child method");    }    public int getParentStaticVar() {        return super.ParentVar;    }    public static void parentStaticMethod() {        System.out.println("this is a Child static method");    }}/* *  */class Parent {    public int ParentVar = 5;    public static int ParentStaticVar = 4;    public static String ParentStaticStr = "parent";        static {        System.out.println("this is a parent static block");    }    public Parent() {        System.out.println("this is a parent  construct");    }    public void parentMethod() {        System.out.println("this is a parent method");    }    public static void parentStaticMethod() {        System.out.println("this is a parent static method");    }}


打印的结果是:

this is a parent static block
this is a Child static block
this is a parent construct
this is a Child construct
5
4
parent
15
14
parent
this is a Child method
this is a parent static method
this is a Child method
this is a Child static method

通过学习,把我对这些了解的与大家共享一下,望能有更多的交流

1)类被自动执行的顺序  
静态域(类被加载时)  
静态初始化块(类加载时,当然这时的静态域要先有值,才便于正确执行)  
非静态域(实例开辟内存时)  
非静态初始化块(实例开辟内存时)  
构造方法(实例生成对象引用时)  
2)当实例化一个第3代的类时,发生的动作将是这样的  
加载第3代,但第3代来源于第2代  
所以加载第2代,但第2代来源于第1代  
所以加载第1代。  
所以:  
(1)第1代类被加载,发生第1代类加载时的动作(即,静态初始化块)  
(2)第2代类被加载,发生第2代类加载时的动作  
(3)第3代类被加载,发生第3代类加载时的动作  
加载完之后,开始创建第3代,但第3代来源于第2代  
所以创建第2代,但第2代来源于第1代  
所以创建第1代  
所以  
(4)第1代被创建,并初始化,完成该时期的动作(即,非静态初始化块,接着 构造方法)  
(5)第2代被创建,并初始化,完成该时期的动作  
(6)第3代被创建,并初始化,完成该时期的动作  
继承父类的理解[]  
从个人理解上看:  
创建父类对象的证据是:子类里都有一个super,它就是父类对象,可见,要创建子类,一定会先创建父类,只是父类做为子类的一个属性(可以这么理解)所以整体上看,是只创建了一个子类。  
简明地说:  
设计者让子类的初始化是首先用父的构造方法来展开的,所以子类在完成造构之前(刚完成调用父类的构造方法展开)父类就实例化了。  
所以我理解了,为什么有的程序只是创建一个对象,却执行了满世界的代码了  
还有一重大发现:  
当父类有多个造构方法时,在子类的构造方法里,可以决定自己是用父类的那个构造方法生成的,所以super()只能用一次,且必须放在构造方法的第一句。  
可见,java在代码复用上下的功夫真不少:  
1)父类的代码可以供所有的子类使用  


2)子类在继承父类时,可以选择不同的父类构造方法,得到功能不同的子类(注,只是选择了一个方法,就能达到功能不同,可见代码重用性又提高了)  
注:创建子类时,都会调用父类的构造方法来初始化,系统默认调用无参的父类构造方法。  
若子类的构造方法里,没有指明用父类的构造方法来初始化,则系统自动添加父类的无参构造方法,  
要是此时,父类没有无参的构造方法时,这些将出现编译报错了。(呵呵,编译器还是满厉害的)  
默认情况下,所有的类都有无参构造方法,但自定了构造方法后,系统自带的无参构造方法将不存在,除非再自定义一个无参构造方法 
呵呵,似乎话多了!这是我平常记录的。

对我提的问题,我还有一个思路:
  变量的值取决于我们定义的变量的类型,而不是创建的对象的类型,这与编译器是在什么时候(编译、运行)进行匹配的有关系?为什么要分不同的时期匹配?

[解决办法]
子类覆盖父类的方法与属性后,把子类强制转化为父类类型,为什么这时方法体是子类的,而属性却是父类的呢? 
我就来说说这句。。
关于多态的问题,我一直以现实生活中的例子来理解。比如交通工具是父类,自行车和小汽车都是继承他的子类,我新建一个自行车的交通工具,他的行驶方式肯定是脚踏,而不是开动发动机。同理,对于新建一个小汽车的交通工具,他的行驶方式 肯定是开动发动机而不是脚踏。而由于他们都是继承自交通工具,他们肯定拥有交通工具应该具有的一些属性,比如有轮子,能行驶,需要掌握方向等。在此基础上,子类可以扩展自己拥有的属性。。
[解决办法]
override仅仅是说对父类方法的重新定义,与属性无关.
而且override机制对父类的static/private和final方法无关
父类的属性只能够隐藏.
[解决办法]
方法产生多态,而属性不产生多态
[解决办法]
父亲有钱先养活了多个孩子,父亲老了没能力赚钱了,只能靠孩子养活了。
今天感恩节,节日快乐。
[解决办法]
"创建父类对象的证据是:子类里都有一个super,它就是父类对象,可见,要创建子类,一定会先创建父类,只是父类做为子类的一个属性(可以这么理解)所以整体上看,是只创建了一个子类。 "

调用父类的构造方法,初始化子类从父类继承下来的成员变量
[解决办法]
多态只对方法,属性不产生多态。


[解决办法]
属性只能被隐藏而不能被覆盖,静态的属性和方法属于类而不是对象
[解决办法]
结果应该是这样的吧
this is a parent static block
this is a Child static block
this is a parent construct
this is a Child construct
5
4
parent
15
14
child
this is a Child method
this is a parent static method
this is a Child method
this is a Child static method

[解决办法]
方法是动态绑定的,属性不是喵~~``
[解决办法]
这样说吧,多态,只有方法才有多态一说,属性是没有这个说法的.
多态必须满足的条件是:继承,方法的覆盖,以及父类引用指向子类对象.这时候调用的方式是子类的,当然,前提是非static和非private方法.
属性只有隐藏一说,不可能满足多态的条件.父类的引用,它的类型还是父类的类型,调用的属性还是父类的属性.

热点排行