新手请教,很惭愧地发现,多态还没学透请教高人下述代码,当子类向上转型,成为父类时,此时的父类,成员变量访问的是父类的,而方法却是子类的,这是怎么回事?我认为强转后,应该都访问子类的呀.package com.ocjp.polymorphism;public class Child extends Parent {
String name;
static String str = "static child"; Child(String s){ this.name = s; x=2;}
void happy(){
System.out.println("child is happy");
}
public static void main(String[] args) {
Child c = new Child("Mike");
Parent p = (Parent)c;
System.out.println(p.name);
System.out.println(c.name);
System.out.println(p.str);
//子类向上转型为父类后,可以访问到父类字符串常量...

System.out.println(c.str);
p.happy(); //子类向上转型为父类后,父类只能看到子类重写后的方法???
c.happy(); 
}
}class Parent{
String name;
int x;
static String str = "static parent";
Parent(){ name = "Parent"; x=1;}
Parent getParent(){return this;}
void happy(){
System.out.println("parent is happy");
}
}
运行结果:
Parent
Mike
static parent //成员变量是父类的;这是为什么呢?我认为强转后,应该都访问子类的呀.
static child
child is happy //方法却是子类的;
child is happy
继承

解决方案 »

  1.   

    由于str是一个静态变量,那么在对其进行访问时,可以直接用类型.str进行访问
    那么这一句代码
    Person p = ...;
    System.out.println(p.str);
    由于是静态变量,那么当通过应用进行访问时,java虚拟机只会判断是哪一个类里面的静态变量,然后进行调用,而不会去判断p到底是什么类型,看下面一段代码
    Person p = null;
    System.out.println(p.str);  //这里可以输出,没有报错,想一下吧
      

  2.   

    属性不存在重写,只有方法(非私有方法、非静态方法、非final方法) 才存在重写,才能发生多态
      

  3.   

    非常感谢一针见血。我基础很差又有2个案例想继续讨教第一个问题是:继承关系中,父子类有相同的方法时,调谁的方法,不是取决于对象么?我将代码贴上来,您帮我分析一下,我的理解错在哪里?package com.ocjp.polymorphism;public class ParamPolymorphism extends ParamParent {
    String name = "child";

    //因为参数不同,这里不能算是重写这个方法可以有比父类更严格的权限
    private String getName(ParamPolymorphism p){
    return p.name;
    }

    public static void main(String[] args) {
    ParamPolymorphism child = new ParamPolymorphism(); ParamParent parent = new ParamParent();

    //问题一:child对象调用getName()方法时,需要的参数为子类,我传了父类,这不是相当于把父类转成子类了么?
    //ParamPolymorphism child = (ParamPolymorphism) new ParamParent();这样把子类转父类不行,为什么方法传参时可以?
    //问题二:child.getName(parent),子类为什么调用的竞争是父类的getName()? System.out.println(child.getName(parent)); //Output: Parent
    System.out.println(child.getName(child)); //Output: Child
    }

    }class ParamParent{
    String name = "Parent";
    String getName(ParamParent p){
    return p.name;
    }
    }
      

  4.   

    第二个问题,是与数组相关的,对象转型。当一个Object对象转成数组时,它是不是违背了父类不能转成子类的原则?第3套考题,第6道,我选不对P277页。package com.ocjp.array;
    import java.util.*;public class ArrayWArraylist {
     
    public static void main(String[] args) {

    ArrayList[] ls = new ArrayList[3];
     for(int i = 0; i < 3; i++) {
     ls[i] = new ArrayList();
     ls[i].add("a" + i);
     }
    //数组转成对象,父类引用指向子类;o作为一个普通的对象,指向仍然是数组;
     Object o = ls; 
     do3(ls);
    for(int i = 0; i < 3; i++) {
    //问题一:Object对象向下转型成数组?是不是又违背了“父类不能强转成子类“的原则?为什么运行时不抛CastClassException?
     System.out.print(((Object[])o)[i] + " ");
    //
     System.out.print(((ArrayList[])o)[i]+"###");
     }

    }
     
    static Object do3(ArrayList[] a) {
     for(int i = 0; i < 3; i++) a[i].add("e");
     return a;
    }
    }
      

  5.   

    问题2,是不是还是因为多态?所有的类,都隐性地extends Object。所以它可以向下转型为数组问题1,难道是方法重载么?子类居然可以重载父类的方法?根据参数来选择到底调用哪个方法?
      

  6.   

    第一个问题,就是重载
    子类当然可以重载父类的方法,因为子类首先就继承了父类的方法,变成了自己的方法
    String getName(ParamPolymorphism p)
    String getName(ParamParent p)
    这两个函数参数类型就不一样,不存在多态问题
      

  7.   

    第二个
    这个Object之所以能转成数组,是因为它本来就是数组转过来的,也就是说它看起来是Object但实际内容还是个数组,所以不会出错
    所谓的“子类可以转换成父类,父类不能转换成子类”是说,前者可以直接转换,一定不会出错,而后者必须强制转换,但是有风险,结果不能保证,你给它一个本来就是数组的Object,所以转换成功了,如果你给它一个别的Object,它就出错了
      

  8.   

    楼主去多看看java系列的博客或者专门的书籍。想不通继承的时候就想想现实社会的家族关系,两者是相关联的的。
    http://blog.csdn.net/gideal_wang/article/details/4913965