Yes, Thread implements Runnable .
As references to the APIs, the runnable is intended to provide a common protocol for objects that want to execute code while they are active.
You are confused because there are two ways to make this kind of concurrency in Java:
- you can extend the
Thread class overriding the default run method, then call the thread in the same way as new MyThread().start() - you can write a class that implements the
Runnable interface and starts it in the same way: new Thread(new MyRunnable()).start()
These approaches are IDENTICAL . The infact run method of the Thread class usually calls the run method of the Runnable object, attached to the thread, if any, otherwise it returns.
What is the Runnable interface for? This is useful because it declares a protocol that allows classes with specific characteristics to be considered.
This is the same in the Comparable or Serializable interface, but here you really have a redefinition method ( public void run() ), while Serializable is just a trait that you give to your class.
The final example is the fact that TimerTask implements Runnable . TimerTask used together with the Timer class to perform pending or periodic tasks, so it makes sense that timertask also starts, so Timer can run tasks using this particular method.
EDIT: since you seem confused by the usefulness of the interface, you need to think that: Java is a statically typed language . What does it mean? This means that he must know everything about the type at compile time to ensure that a runtime type error is never thrown.
Ok, now suppose the Java API supports the hipotetically class for drawing shapes. This way you can write your own classes for shapes, and then pass them to this class (call ShapeDrawer on it).
ShapeDrawer needs to know how to draw the shapes you pass, and only to be sure of this, to decide that each Shape object must have a method called public void drawMe() , so that a ShapeDrawer can call this method on every Shape that you attach to it without knowing anything more.
So you declare the interface
public interface Shape { public void drawMe(); }
that classes can be considered a Shape . And if the class is Shape , you can pass it to the ShapeDrawer class without any problems:
class ShapeDrawer { public void addShape(Shape shape) { ... } public void drawShapes() { for (Shape s : shapes) s.drawMe(); } }
So, the compiler is happy because when you add shapes, you add classes that implements Shape , your class knows exactly how to draw such shapes, and the developers are pleased that you have separated the general protocol of the object from their specific implementations.
This is a kind of contract, if you need a Triangle class that can be drawn by the ShapeManager , you need to declare this method so that you can call, for example,
shapeDrawerInstance.addShape(new Triangle())