Why is implementing Runnable a better option than extending from Thread class?
相关问题
- Delete Messages from a Topic in Apache Kafka
- Jackson Deserialization not calling deserialize on
- How to maintain order of key-value in DataFrame sa
- StackExchange API - Deserialize Date in JSON Respo
- Difference between Types.INTEGER and Types.NULL in
It might not make any sense in your inheritance hierarchies to extend
Thread
. Only extendThread
if you wish to modify the functionality ofThread
s.With
Runnable
, any class in any inheritance hierarchy can expose a task that can be seen as a unit of work to have aThread
perform.Because IS-A really isn't what you want. Your class wants to be Runnable, but IS-A Thread feels too strong. That's what inheritance is saying. You really just want to implement the run() method, not all the other attendent stuff in the Thread class.
This falls in line with Scott Meyers very good advice in "More Effective C++": Make non-leaf classes abstract. Substitute interfaces and you're spot on.
To answer the question first:
If you extend thread, an instance of your class (extended thread) will always call the constructor of the superclass thread. So MyClass myclass = new MyClass() will always calls "super()" inside the constructor of MyClass which instantiates a thread, and in the end you may implement some overhead into your class (if you don't use any method of the superclass thread). So implementing only Runnable allows your class running faster without any inherited overhead.
Further, there are some wrong answers here:
Didn't you ever consider to create an object without any interface? Because it would be very wrong to implement an interface for every object!
Wrong, everytime you call the constructor of a class, you will get an own object, it doesn't matter from where it is extended or what it implements!
Conclusion: In java, EVERY class instance is an object, and extends the class Object (while primitives aren't...only array of primitives like int[] classes extends Object, and such arrays have the same methods like any object - but sadely they're not mentioned in the Javadoc! The Sun guys probably didn't want us to use them).
Btw there are at least two advantages of inheritance: Code sharing and a clear Javadoc. Because if you inherite from a class, you can see all subclasses in the Javadoc. You could do that with an interface too, but then you can't share code. Even more, then you would need to create "nested" objects and call the constructor of two or more objects instead of only one, and this again would mean you implement some overhead from the superclass Object itself! Because there is no object in Java without overhead, and creating as less objects as possible is quite important for high performance applications. Objects are the greatest thing, but unnecessairy objects aren't...
This way you decouple the computation (the what) from the execution (the when and/or the how).
With
Runnable
orCallable
, you can for instance submit many work/computation to anExecutor
which will take care to schedule the stuffs. Here is an excerpt form ExecutorService:Using
Runnable
/Callable
gives you more flexibility that using Threads directly.The actual point to take away is that implements is ALWAYS preferred over extends on any questionable cases.
Extends binds two class files very closely and can cause some pretty hard to deal with code.
When I first "understood" OO programming I was extending EVERYTHING, but it turned my whole design into mush. Now I extend just the few things that clearly and obviously pass the "is-a" test and everything else is an interface...
Many many problems just stopped happening (Confusing multiple inheritance situations, time wasted refactoring hierarchies, the tendency to have "protected" variables then wonder why they are changing when you didn't change them in the current class, chaining requirements for constructors, figuring out how different inheritance-trees interact with each other, ...
It seems like every 3 years (for the last 20) I think I really "Get" programming and look back at the stupid things I did 3 years ago in shame... This was one of those instances (but from closer to 7 years ago at this point)
The reasons why you might prefer implementing the Interface Runnable to extending the Class Thread are the following:
Source: a blog - I'm not quite sure if that's correct