继承VS接口(Thread与runnable的比较)
Published On March 03, 2015
我们一直以一个API的使用者的角度来比较Java中继承和接口的区别。这里我不想详述,这篇博文从作用和设计理念两方面叙述得很好了。
今天我们来从API设计者的角度出发,以我们最耳熟能详的多线程调用,extends Thread 和 implements Runnable
来探究Java中继承和接口的实现方式。
不知道大家想过没有,我们写一个类,实现Runnable接口,重写run()
函数了以后,就可以用这个类来创建多线程,run()
里面的代码会被反复调用。那么请问多线程运行过程中需要的其他函数怎么实现?
如果你已经思考清楚了这个问题,那么恭喜你,这篇博文对你来说已经是隔年皇历。如果你和当时的我一样疑惑这个问题,那么接下来你要仔细看了。
我们先比较一下两种方法实现多线程调用上的区别 source
public class HelloThread extends Thread {
public void run() {
System.out.println("Hello from a thread!");
}
public static void main(String args[]) {
(new HelloThread()).start();
}
}
public class HelloRunnable implements Runnable {
public void run() {
System.out.println("Hello from a thread!");
}
public static void main(String args[]) {
(new Thread(new HelloRunnable())).start();
}
}
开源的JDK
JDK是开源的,从JDK6开始,你在JDK安装目录下可以找到src.zip这个文件,就是其源代码,可以导入eclipse的。 导入JDK源代码后,在你的代码里按住Ctrl并点类名或方法名就看到源代码了。
但是JDK底层实际上为了跨平台用的是C/C++调用平台本身的功能,这部分JDK的src.zip不包含,但是在Oracle领导的OpenJDK这个项目里面可以看到其开源实现。
接下来我们把Runnable.java和Thread.java进行仿写,理解通过继承和接口两个不同方法来实现同一个功能的区别。
仿写
模仿runnable,runnable接口下只有一个函数run()
。
//Animal.java (interface)
package interfacetest;
public interface Animal {
abstract String run();
}
//developer.java (模仿Thread的类)
package developer;
import interfacetest.Animal;;
public class developer implements Animal{
Animal target;
public String run() {
if(target!=null)
return target.run();
else return null;
}
public void display() {
System.out.println(""+run());
}
public developer() {
}
public developer(Animal target) {
this.target=target;
}
}
//Cat.java (继承实现)
package interfacetest;
import developer.developer;
public class Cat extends developer{
@Override
public String run() {
return "Cat run";
}
}
//Dog.java (接口实现)
package interfacetest;
import developer.developer;
public class Dog implements Animal{
public String run() {
return "Dog run";
}
}
//MainActivity.java (测试类)
package interfacetest;
import developer.developer;
import interfacetest.Cat;
import interfacetest.Dog;
public class MainActivity {
public static void main(String[] args) {
// TODO Auto-generated method stub
Cat c = new Cat();
Dog d = new Dog();
c.display();
new developer(d).display();
}
}
//测试结果
Cat run
Dog run
结论是众所周知的,建议使用接口以获得更多扩展。因为一个Class只能继承一个父类,但是可以实现多个接口。
Tags: Java