遇到一种奇怪的方式,同时extends Thread与implements Runnable,这时怎么处理呢?请教各位老师

时间:2021-01-14 17:34:57

public class Explorer3 {
    public static void main(String[] args) {
Runnable r = new Runnable() {
    public void run() {
System.out.print("Cat");
    }
};
Thread t = new Thread(r) {
    public void run() {
System.out.print("Dog");
    }
};
t.start();
    }
}

我知道比如new Thread(Runnable r).start()的时候,是调用target的run方法,即Runnable r中的run方法
而直接new Thread().start()时候,调用的是thread类中的run()方法

可这题中调用的结果是Thread中的run,即输出Dog,而为何不调用Runnable中的run输出Cat呢?

22 个解决方案

#1


因为你没有让r start一下

#2


因为t的run方法覆盖了r的run方法

#3


顶楼上的。。覆盖掉了

#4


引用 1 楼 knightzhuwei 的回复:
因为你没有让r start一下

谢谢这位回帖,不过r是不需要手动去start的

#5


引用 2 楼 MT502 的回复:
因为t的run方法覆盖了r的run方法

能请这位老师说一下,这种覆盖是基于什么呢?继承还是实现? 还是说如果Thread中与Runnable中同时定义了run,就以Thread中的为准?

#6


thread类的start方法应该先是去调用自身的run()方法,如果没有再去找runnable的run()方法

#7


晕。。看错了。。

#8


up

#9


这是因为你重写了t的run方法,所以调用的是t的,楼主可以试下,如果没有重写t的run方法,就会去调用r了

#10


因为如果通过Thread t = new Thread(r)来创建线程的话,t的run方法实现本来默认就是调用r的run方法的,但是楼主重写了t的run方法,所以r就执行不到了

#11


Thread t = new Thread(r) {

            public void run() {
                System.out.println("Dog");
            }
        };
这里你是使用的继承机制实现的线程,而且重写了run()方法,根据多态机制,自然是调用你在子类中重写的run()方法。

如果你不使用继承机制,而使用
Thread t = new Thread(r);
这时候自然是调用Thread中的run()方法。
Thread中的run实现方式是:
public void run() {
if (target != null) {
    target.run();
}
    }

这里的target是通过new Thread(r);里的r赋值而来。
因此,只要传入了参数Runnable r,调用的就是接口实现类中的run()方法。如果没有传入参数r,也就不执行任何功能了。

#12


如果没重写t的run方法,线程启动后开始执行t的run方法,如果r不为null该方法将会调用r的run方法。但如果重写t的run方法,线程启动后执行完System.out.print("Dog");就结束了。
这不是以谁为准的问题,也不用死记,把流程弄明白就可以了。

#13


Runnable是为了弥补对象extends Thread 就不能继承其他的对象

干嘛要一起用

当一起实现的话 最后共享一个run

#14


好久的帖子了。。。學習一下。。

#15


引用 11 楼 zangxt 的回复:
Thread t = new Thread(r) {

  public void run() {
  System.out.println("Dog");
  }
  };
这里你是使用的继承机制实现的线程,而且重写了run()方法,根据多态机制,自然是调用你在子类中重写的run()方法。

如果你不使用继承机制,而使用
Thread t = new Thread(r);
这……

Thread t=new Thread(r);
调用实现Runnable接口的类的run方法。

#16


看JDK中Thread类的run方法源码就知道了

#17


嗯,这种问题看下Thread的源码就知道了!

#18


1】
public interface RunTest {

void run();
}
2】
public class RunTestImpl implements RunTest {

public RunTest target;
public  RunTestImpl(RunTest target){
this.target=target;
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("I was called!");
     if(target!=null){
     target.run();
      }
}

}
3】
  public class Test1 {

/**
 * @param args
 */
public static void main(String[] args) {
// TODO Auto-generated method stub
RunTest  t1=new RunTest() {

@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("my runtest");

}
};

RunTestImpl  t2=new RunTestImpl(t1);
RunTestImpl  t3=new RunTestImpl(t1){
public void run() {
// TODO Auto-generated method stub
System.out.println("myimpl runtest");

}
};
System.out.println("t2:");
t2.run();
System.out.println("t3:");
t3.run();
}

}
//OUTPUT:
t2:
I was called!
my runtest
t3:
myimpl runtest

#19



public class ThreadTest {

/**
 * @param args
 */
public static void main(String[] args) {

MyRunnable t=new MyRunnable();
Thread t1=new Thread(t);
t1.start();
MyThread myThread=new MyThread(t);
myThread.start();
}

}
class MyThread extends Thread{
public void run(){
System.out.println("Mythread!");
}
public MyThread(Runnable t){
super(t);
}
}
class MyRunnable implements Runnable{

@Override
public void run() {

System.out.println("Myrunnable!");
}

}
------------------------------------------------------------------
result:
Myrunnable!
Mythread!

#20


你实现的Runable都没有
new Thread(r).start();
一下咋运行啊~~~

#21


不用说那么多,  简单总结下..  就是多态,
LZ如果不知道多态是什么的话, 回去温习下基础

#22


该回复于2011-12-12 09:13:52被版主删除

#1


因为你没有让r start一下

#2


因为t的run方法覆盖了r的run方法

#3


顶楼上的。。覆盖掉了

#4


引用 1 楼 knightzhuwei 的回复:
因为你没有让r start一下

谢谢这位回帖,不过r是不需要手动去start的

#5


引用 2 楼 MT502 的回复:
因为t的run方法覆盖了r的run方法

能请这位老师说一下,这种覆盖是基于什么呢?继承还是实现? 还是说如果Thread中与Runnable中同时定义了run,就以Thread中的为准?

#6


thread类的start方法应该先是去调用自身的run()方法,如果没有再去找runnable的run()方法

#7


晕。。看错了。。

#8


up

#9


这是因为你重写了t的run方法,所以调用的是t的,楼主可以试下,如果没有重写t的run方法,就会去调用r了

#10


因为如果通过Thread t = new Thread(r)来创建线程的话,t的run方法实现本来默认就是调用r的run方法的,但是楼主重写了t的run方法,所以r就执行不到了

#11


Thread t = new Thread(r) {

            public void run() {
                System.out.println("Dog");
            }
        };
这里你是使用的继承机制实现的线程,而且重写了run()方法,根据多态机制,自然是调用你在子类中重写的run()方法。

如果你不使用继承机制,而使用
Thread t = new Thread(r);
这时候自然是调用Thread中的run()方法。
Thread中的run实现方式是:
public void run() {
if (target != null) {
    target.run();
}
    }

这里的target是通过new Thread(r);里的r赋值而来。
因此,只要传入了参数Runnable r,调用的就是接口实现类中的run()方法。如果没有传入参数r,也就不执行任何功能了。

#12


如果没重写t的run方法,线程启动后开始执行t的run方法,如果r不为null该方法将会调用r的run方法。但如果重写t的run方法,线程启动后执行完System.out.print("Dog");就结束了。
这不是以谁为准的问题,也不用死记,把流程弄明白就可以了。

#13


Runnable是为了弥补对象extends Thread 就不能继承其他的对象

干嘛要一起用

当一起实现的话 最后共享一个run

#14


好久的帖子了。。。學習一下。。

#15


引用 11 楼 zangxt 的回复:
Thread t = new Thread(r) {

  public void run() {
  System.out.println("Dog");
  }
  };
这里你是使用的继承机制实现的线程,而且重写了run()方法,根据多态机制,自然是调用你在子类中重写的run()方法。

如果你不使用继承机制,而使用
Thread t = new Thread(r);
这……

Thread t=new Thread(r);
调用实现Runnable接口的类的run方法。

#16


看JDK中Thread类的run方法源码就知道了

#17


嗯,这种问题看下Thread的源码就知道了!

#18


1】
public interface RunTest {

void run();
}
2】
public class RunTestImpl implements RunTest {

public RunTest target;
public  RunTestImpl(RunTest target){
this.target=target;
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("I was called!");
     if(target!=null){
     target.run();
      }
}

}
3】
  public class Test1 {

/**
 * @param args
 */
public static void main(String[] args) {
// TODO Auto-generated method stub
RunTest  t1=new RunTest() {

@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("my runtest");

}
};

RunTestImpl  t2=new RunTestImpl(t1);
RunTestImpl  t3=new RunTestImpl(t1){
public void run() {
// TODO Auto-generated method stub
System.out.println("myimpl runtest");

}
};
System.out.println("t2:");
t2.run();
System.out.println("t3:");
t3.run();
}

}
//OUTPUT:
t2:
I was called!
my runtest
t3:
myimpl runtest

#19



public class ThreadTest {

/**
 * @param args
 */
public static void main(String[] args) {

MyRunnable t=new MyRunnable();
Thread t1=new Thread(t);
t1.start();
MyThread myThread=new MyThread(t);
myThread.start();
}

}
class MyThread extends Thread{
public void run(){
System.out.println("Mythread!");
}
public MyThread(Runnable t){
super(t);
}
}
class MyRunnable implements Runnable{

@Override
public void run() {

System.out.println("Myrunnable!");
}

}
------------------------------------------------------------------
result:
Myrunnable!
Mythread!

#20


你实现的Runable都没有
new Thread(r).start();
一下咋运行啊~~~

#21


不用说那么多,  简单总结下..  就是多态,
LZ如果不知道多态是什么的话, 回去温习下基础

#22


该回复于2011-12-12 09:13:52被版主删除