jQuery in Action, 2nd edition*
The moose likes Java in General and the fly likes when extend a class Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCA/OCP Java SE 7 Programmer I & II Study Guide this week in the OCPJP forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "when extend a class" Watch "when extend a class" New topic
Author

when extend a class

Leandro Coutinho
Ranch Hand

Joined: Mar 04, 2009
Posts: 417
From the book SCJP1.6 K&B talking about implement Runnable or extend the Thread class:
...Extending the Thread class is the easiest, but it's usually not a good OO practice. Why? Because subclassing should be reserved for specialized versions of more general superclasses. So the only time it really makes sense (from an OO perspective) to extend Thread is when you have a more specialized version of a Thread class.

What does "more specialized version" mean? Does it mean override a method?

I'm creating this topic mainly because of the JFrame class. The Sun's examples always extend JFrame. Why? Just for convenience?
Why instead of use inheritance, they don't have an instance of JFrame?

Maybe the answer can be explained using the Car and Ferrari example. Of course that Ferrari IS-A car, so it should extend Car. It doesn't make sense have an instance of Car in the Ferrari class.

Is this the same case with JFrame?
Embla Tingeling
Ranch Hand

Joined: Oct 22, 2009
Posts: 237
Leandro Coutinho wrote:Just for convenience?


In principle there's no difference between Thread and JFrame from an inheritance point of view. The difference is that you're seldom interested in making new kinds of Threads. What you want is to have your code run by a Thread and then you may use the Thread/Runnable pair.

Extending Thread and extending JFrame are examples of ordinary class inheritance. Using the Thread/Runnable pair is an example of the Strategy design pattern.

BUT, Thread implements Runnable and this makes it an example of the Template Method design pattern and no one can claim that this is bad OO practice. So I agree with you. You don't necessarily extend Thread for the purpose of making a new kind of Thread. You extend it for the purpose of "hooking" into the Thread algorithm, which is to execute code in its own thread, and this is perfectly fine OO. So the source you're referring to is definately wrong here.

What it boils down to is that when you want to utilize Thread to run your code in its own thread you have a choise of two design patterns, Strategy and Template Method. Both are equally good OO so it's a question of what you prefer really. The latter involves extending Thread but not for the purpose of making a new kind of Thread. You extend Thread for the purpose of overriding the run method which Thread has left for you to supply in accordance with the Template Method design pattern.
Leandro Coutinho
Ranch Hand

Joined: Mar 04, 2009
Posts: 417
Thanks for your reply.

I would like to know:
- What does "more specialized version" mean? Does it mean override a method?
- Does Ferrari extend Car is the same case with Sun(the company) extend JFrame in its examples?

Strategy pattern is just a way to use polymorphism.
Template Method pattern is similar to the Strategy patter. The difference is that in the Template Method, only some steps are replaced and the order in which the overridden methods will be executed is controlled by a template method defined in the superclass, hence the name of the pattern.

Why do you think that Thread implementing Runnable is an example of the Template Method? There's no template method.
Dave Wingate
Ranch Hand

Joined: Mar 26, 2002
Posts: 262
Leandro Coutinho wrote:
I would like to know:
- What does "more specialized version" mean? Does it mean override a method?


Considering the Thread/Runnable combination, there are two important and separate concerns in play:

- Define WHAT unit of work is to be executed. This concern gets defined in the Runnable.

- Define HOW to execute a unit of work in a separate thread. This concern gets defined in the Thread. There are potentially many different nuances to this "how" concern. For example, we might want to write a log message whenever a new Thread is created or executed. In such cases, you could define a more specialized version of Thread.

Here's a toy example, demonstrating the distinction described above:



Fun programming etcetera!
Leandro Coutinho
Ranch Hand

Joined: Mar 04, 2009
Posts: 417
Thanks for your reply.

Ok. I understand what you mean.
I have one doubt about your code. I don't understand how the run method in the LoggingThread class is called.
I know that the run method is executed after the method start is called, but not in this case because the overridden method start doesn't call the method run.
The output is:
Created a new thread to service a Runnable.
Begin executing a Runnable in the background.
Doing some useful, long-running unit of work.
Completed the LoggingThread$1@42e816 unit of work in 0 miliseconds.

Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18916
    
  40

Leandro Coutinho wrote:I have one doubt about your code. I don't understand how the run method in the LoggingThread class is called.
I know that the run method is executed after the method start is called, but not in this case because the overridden method start doesn't call the method run.


The overridden start() method doesn't call the run() method. It does, however, call the super.start() method, which starts a new thread that calls the run() method.

Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Leandro Coutinho
Ranch Hand

Joined: Mar 04, 2009
Posts: 417
But the run() method in the Thread class that should be executed, right?
He called the super constructor passing an implementation of Runnable as parameter, that just prints "Doing some useful, long-running unit of work."
So I don't understand how the run() method in the LoggingThread class is called. Please help me.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18916
    
  40

Leandro Coutinho wrote:But the run() method in the Thread class that should be executed, right?
He called the super constructor passing an implementation of Runnable as parameter, that just prints "Doing some useful, long-running unit of work."
So I don't understand how the run() method in the LoggingThread class is called. Please help me.


Okay, this may get a bit convoluted... The constructor will store the runnable object that is passed into an instance variable -- it doesn't mean that the start() method will call it.

The start() method starts a new thread, which calls the run() method of thread class. Since the logging thread class overrides the run() method, it is that run method that will be called. One of the operations that this run() method does is to call the super.run() method, which by default, will call the run() method of the runnable object that is passed into the constructor.

Henry
Dave Wingate
Ranch Hand

Joined: Mar 26, 2002
Posts: 262
Leandro Coutinho wrote:But the run() method in the Thread class that should be executed, right?
He called the super constructor passing an implementation of Runnable as parameter, that just prints "Doing some useful, long-running unit of work."
So I don't understand how the run() method in the LoggingThread class is called. Please help me.


Calling the start() method on the Thread class starts a new background thread that executes the Thread's run() method:
http://java.sun.com/javase/6/docs/api/java/lang/Thread.html#start%28%29

So what does the Thread's run() method do? The key insight is that, because the Thread was constructed with a Runnable argument, the Thread's run method will call the run() method of the Runnable:
http://java.sun.com/javase/6/docs/api/java/lang/Thread.html#run%28%29
Leandro Coutinho
Ranch Hand

Joined: Mar 04, 2009
Posts: 417
Dave Wingate wrote:Calling the start() method on the Thread class starts a new background thread that executes the Thread's run() method:
http://java.sun.com/javase/6/docs/api/java/lang/Thread.html#start%28%29

So what does the Thread's run() method do? The key insight is that, because the Thread was constructed with a Runnable argument, the Thread's run method will call the run() method of the Runnable:
http://java.sun.com/javase/6/docs/api/java/lang/Thread.html#run%28%29

I know this. That is why I had doubt.
super(target);
The run() method of the target:
public void run() {
System.out.println("Doing some useful, long-running unit of work.");
}

This is how I saw the execution of this program:
1 - An implementation of Runnable (target) is created. Its run method just prints: "Doing some useful, long-running unit of work."
2 - The target is passed as parameter to the LoggingThread constructor.
3 - The LoggingThread constructor is invoked.
4 - The super (Thread) constructor is invoked and receives the target created in step 1.
5 - The instance Runnable of the LoggingThread also receives the target.
6 - First output: "Created a new thread to service a Runnable."
7 - The start method of the LoggingThread class is invoked.
8 - Second output: "Begin executing a Runnable in the background."
9 - The start method of the Thread class is invoked.
10 - The run method of the Thread class is invoked.
11 - The run method of the target which is an instance of the Thread class is invoked.
12 - Third output: "Doing some useful, long-running unit of work."

The error in my steps starts in step 10. Actually the run method of the LoggingThread class is invoked, and not of the Thread class.
I just figured out why. Polymorphism plays a role here. Look the code below:

I thought that it would print "Hi from A", but it prints "Hi from B"

Thank you folks!
Embla Tingeling
Ranch Hand

Joined: Oct 22, 2009
Posts: 237
Leandro Coutinho wrote:Why do you think that Thread implementing Runnable is an example of the Template Method? There's no template method.


There is for sure, the run method.

Why don't you simply have a look at the Thread documentation,

http://java.sun.com/javase/6/docs/api/java/lang/Thread.html

The "two ways to create a new thread of execution" mentioned there are clear-cut cases of Template Method and Strategy.

For my arguments why the authors of the SCJP1.6 K&B quote are wrong, I refer back to my previous post.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18714
    
    8

Leandro Coutinho wrote:I'm creating this topic mainly because of the JFrame class. The Sun's examples always extend JFrame. Why? Just for convenience?
Why instead of use inheritance, they don't have an instance of JFrame?


I think it's historical. That's the way things were done back then. It isn't even any more convenient for a class to extend JFrame instead of having a JFrame instance variable, so I don't think that was the reason.

Quite likely if they were writing the tutorials now, they would have an instance of JFrame (composition) rather than being an instance of JFrame (inheritance). But the original tutorials were written in a simpler time, before the theoreticians of object-orientation started to have the influence which they have today.
Leandro Coutinho
Ranch Hand

Joined: Mar 04, 2009
Posts: 417
Paul Clapham wrote:
Leandro Coutinho wrote:I'm creating this topic mainly because of the JFrame class. The Sun's examples always extend JFrame. Why? Just for convenience?
Why instead of use inheritance, they don't have an instance of JFrame?


I think it's historical. That's the way things were done back then. It isn't even any more convenient for a class to extend JFrame instead of having a JFrame instance variable, so I don't think that was the reason.

Quite likely if they were writing the tutorials now, they would have an instance of JFrame (composition) rather than being an instance of JFrame (inheritance). But the original tutorials were written in a simpler time, before the theoreticians of object-orientation started to have the influence which they have today.

Thank you Paul!
Embla Tingeling
Ranch Hand

Joined: Oct 22, 2009
Posts: 237
Paul Clapham wrote:I think it's historical. That's the way things were done back then. It isn't even any more convenient for a class to extend JFrame instead of having a JFrame instance variable, so I don't think that was the reason.

Quite likely if they were writing the tutorials now, they would have an instance of JFrame (composition) rather than being an instance of JFrame (inheritance). But the original tutorials were written in a simpler time, before the theoreticians of object-orientation started to have the influence which they have today.



Come on now, this is Sun's Hello World example and it has been for a long time,



As you can see the JFrame is held in a variable and not extended at this point.

The next step would be to extend the JFrame though and adapt it to your needs. This is ordinary class inheritance and it's the most convinient way to use a JFrame. It's perfectly fine OO and has always been.

At that point the start up code would rather look like this,

Leandro Coutinho
Ranch Hand

Joined: Mar 04, 2009
Posts: 417
Embla Tingeling wrote:Come on now, this is Sun's Hello World example and it has been for a long time,

I said that they extend JFrame, it was not Paul.
They changed some tutorials. Before, everything that is in the createAndShowGUI method was inside the main method and they didn't use javax.swing.SwingUtilities.invokeLater. And it has not been for a long time.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: when extend a class