今天我们老师给我们讲了多态问题,其中关于父类引用指向子类对象.始终不知道是怎么回事,
如THREAD类中的构造函数public Thread(Runnable target)我们老师就说有父类引用指向子类对象,但我看了很久也想不明白,各位能否告诉我哪个是父类引用,哪个是子类对象.以及多态在这个函数里是如何实现的?

解决方案 »

  1.   

    http://blog.csdn.net/Slugfest/archive/2008/01/10/2034305.aspx看这章。
      

  2.   

    对象的正交关系
    对象之间的关系,在功能上可能存在正交性,而我们要尽量地把这种正交性体现出来,于是我们就要重新界定对象的粒度。我们借用Java的Thread类,和Runnable接口作为例子的原型,记住,只是以其为原型,我所讲述的并非是Java的线程。
    class Thread
    {
        void start(Runnable run)
    }interface Runnable
    {
        void run();
    }
    我再次请大家注意的是,我的Thread类并没用实现Runnable类,因为我认为那并不必要,事实上,我们也不鼓励Java的开发人员派生Thread,而是鼓励他们实现Runnable接口。
    (new Thread(new Runnable() { 
                public void run() {}})).start();
    这样的使用方式(除了代码风格外),才是我们鼓励的。但是由于我们只讲必要性,而不涉及到具体使用的方便性,所以我的Thread类没有实现Runnable接口。
    那么我们思考线程对象和Runnable实现类的真实含义,一个线程对象,也许维护了OS的线程内核对象(可能是模拟的,比如Ruby的Fake Thread)。但是线程对象本身可以加载什么方法,或者说在一个线程上做什么事情,那是Runnable实现类要如何描述的问题,这两个对象有着关系,但是在功能上确实正交的。于是,我们把它们分成两个对象的粒度。
    到此,如果我们有一个Timer类,或者一个叫做Fiber的类。我们只是想把我们要做的事情加载到Timer事件中,或者是Fiber纤程上,我们就会更好地意识到Runnable接口和Thread类的正交性。
      

  3.   


    直接来看看用法,可能要好理解一些。你说的Thread类中的那构造方法public Thread(Runnable target),你可以看到参数是一个Runnable类型的。我们一般是这样使用的:先定义一个类,并继承Runnable接口class Test implements Runnable{public void run() {
    ...
    }}
    然后,我们可以利用下面的一行代码来启动线程:
    new Thread(this).start();这里的this就是实现了Runnable接口的类对象。相当于是把一个父类的引用指向了那个新new出来的Thread对象,只不过,该对象没有一个承载变量
      

  4.   

    //如果把动物当作父类,动作叫声是其方法
    //例:
           class Animals
           {
             public Animals()
             {
              }
               public void call()
               {
                }
            }
       // 则狗,猫,,可以看作是其子类 例:           class dog extends Animals
               {
                    public dog()
                    {
                     }
                     public void call()
                     {
                         System.out.println("汪汪");
                      }
                }            class cat extends Animals
                {
                   public cat()
                   {
                    }
                     public void call()
                     {
                        System.out.println("喵喵");
                      }
                 }             public class Test
                {
                     public static void main(String args[])
                     {
                            Animals A = new dog();
                             A.call(); 
                             A = new cat();
                             A.call();
                      }
                 }
               编译运行下,就知道了
      

  5.   

    class A {
    }
    class B extends A{
    }
    A a=new B();
    父类引用指的是a 子类对象指的new B() new出来的那个对象
    父类引用指向子类对象 这个说法只是语言表达上的问题 不是你不懂 而是你没分清什么叫父类引用 什么叫指向String x="abc" abc是个实在的对象 x只是个引用 就好像abc是间房子 x只是个门牌号 你要通过x才能找到那个abc
    x就代表了那个abc 这就叫x指向abc 在实际需要abc的地方 只要用x代替就可了再简单解释下多态的问题
    A a=new B();
    或者
    B b=new B();
    A a=b;因为B继承自A 所以B具备A的基本特征 你把B里比A多出来的东西砍掉 它就是A 所以可以a=b; 但是这个时候并没有把b里多余的东西砍掉 只是让a与b引用同一个对象 在需要的时候可以把b截成A类型 也可以把a还原成B类型
    但是你不能让b指向一个A类型的对象 因为A类型无法转换成B类型 我想这样你应该能大概了解什么叫"父类引用指向子类对象"了同是新手 有错误的地方请高手指正
      

  6.   

    又见甘草兄,这正交性论断我都看起来迷糊,呵呵,估计楼主也很难看懂。不过楼主的问题我可以回答你:public Thread(Runnable target)这个方法是构造一个线程,(为啥你们老师不直接说明哪个是父类呢?呵呵,想不通)在构造一个线程对象的时候,真正的父类就是current Thread。也就是依赖于当前运行着的这个线程,新构造线程的很多属性要从当前运行线程中继承下来,包括daemon,priority还有contextClassLoader等。要证明?呵呵,看JDK源代码Thread类就知道了构造最终调用init方法来实现,而init方法中有这么几行:
    Thread parent = currentThread();this.daemon = parent.isDaemon();
    this.priority = parent.getPriority();
    this.contextClassLoader = parent.contextClassLoader;
    ...看到这几行你估计应该能明白了吧,不过真正要理解线程,还是甘草兄那个境界比较高,呵呵,我还要继续努力学习啊!
      

  7.   

    public Thread(Runnable target)
    因为括号里的参数传递进来的肯定是Runnable的子类 
      

  8.   

    理解下继承的IS-A关系,可以帮助你理解多态