Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Could someone explain this java practice to me 4

Status
Not open for further replies.

pigsie

Programmer
Dec 19, 2000
307
GB
Hi

I have been reading the latest JDC tech tip newsletter and i came across the following line:

Set sethash = new Hashset();

I'm assuming an object of class Set implements the Hashset interface but why not use
Set sethash = new Set();

Instead? What are the advantages (if any ) are there in creating a reference to an object in this way? I've seen this quite often but could never understand why its done.

I've always wondered about this.

Thanks

Kola
 
Hi pigsie,
It's actually the reverse of what you said.
Code:
Set
is an interface and
Code:
HashSet
implements it. The
Code:
Set
reference
Code:
sethash
could refer to any object that implements Set.
One reason for doing this is that you may not know which type of
Code:
Set
implementation you want to use at compile time, some implementatons are thread-safe, others aren't, etc., so you program it to make the decision at runtime, choosing from
Code:
HashSet
,
Code:
TreeSet
, etc.
Hope this Helps,
MarsChelios
 
Thanks for the reply. I'm still a bit confused are you saying that the sethash reference is presently of type Hashset but at run time this reference can be changed to point to any object which implements the HashSet interface?

Thanks
 
Your confusion is understandable, this is getting into the harder concepts in Java, specifically Polymorphism.
First off,
Code:
Set
is the interface, not
Code:
HashSet
.
Code:
HashSet
implements
Code:
Set
and so
Code:
HashSet
has the methods of interface
Code:
Set
.
Some example code might make things clearer. Say we have an uninstantiated instance variable of type
Code:
Set
.
Code:
  private Set set;
Then later on, inside a constructor or method, we decide to instantiate it. At this point we may declare the reference
Code:
set
to refer to any class that implements the
Code:
Set
interface and is not abstract, so we could do:
Code:
  set = new HashSet ();
or
Code:
  set = new LinkedHashSet ();
or
Code:
  set = new TreeSet ();
Code:
set
can reference any of these classes because they implement the interface
Code:
Set
.
However, there's a trick; All of these classes have methods in addition to what
Code:
Set
says they must have, so how can a program that doesn't know what object
Code:
set
is call thjose methods?
The answer, they can't. Because the reference
Code:
set
was declared initialliy as type
Code:
Set
, only the methods in interface
Code:
Set
can be called by it and no others.
So for instance, if
Code:
set
referred to a
Code:
TreeSet
object, the code:
Code:
  set.subSet (from, to);
would give an error, since
Code:
subSet (Objec,t Object)
is defined in
Code:
TreeSet
and not
Code:
Set
.
Hope this clears that up, if it doesn't let me know.
MarsChelios
 
are you saying that at run time we cannot be sure what methods a class has that implements an interface? so we instead make a reference specifying that class so we'll know what methods it supports. Also is it true you cant actually create an instance of an interface?

Thanks
 
Are you saying that at run time we cannot be sure what methods a class has that implements an interface? So we instead make a reference specifying that class so we'll know what methods it supports?
No. I was trying to give an example for coding in this manner, this one is more in depth.
Say based on certain user input that we want to use a
Code:
TreeSet
to structure our data, and on other user input a
Code:
HashSet
, because structure is not important. So somewhere in our code, we might have a statement like this:
Code:
  if (userWantsStructure) {
    treeSet = new TreeSet ();
  }
  else {
    hashSet = new HashSet ();
  }
However, this makes the code twice as long, because whenever we want to add data, we have to see which type the user wants, because we have to use either the
Code:
treeSet
or
Code:
hashSet
. So code to add data would look like this:
Code:
  if (userWantsStructure) {
    treeSet.add (data);
  }
  else {
    hashSet.add ();
  }
This is where your question comes to the rescue. Both of these classes ,
Code:
TreeSet
and
Code:
HashSet
, implement
Code:
Set
. Also, most of the times we need to use these objects, we are using methods defined in
Code:
Set
.
By creating a variable of type
Code:
Set
, like so:
Code:
  private Set set;
and initializing it similar to the example above:
Code:
  if (userWantsStructure) {
    set = new TreeSet ();
  }
  else {
    set = new HashSet ();
  }
we can now do anything that
Code:
Set
defines, no matter whether
Code:
set
refers to a
Code:
TreeSet
or a
Code:
HashSet
. So the code to add data, no matter which object
Code:
set
references, would be:
Code:
  set.add (data);
If we wanted to do something specific with
Code:
TreeSet
or
Code:
HashSet
, then we would have to do the check for which type
Code:
set
references, cast
Code:
set
to that type, and then access the methods needed, shown below:
Code:
  if (set instanceof TreeSet) {
    TreeSet treeSet = (TreeSet) set;
    //Do something with treeSet here 
  }
  else {
    HashSet hashSet = (HashSet) set;
    //Do something with hashSet here 
  }
Also is it true you can't actually create an instance of an interface?
Technically yes. This is a little off topic, but anonymous classes are an exception to this. You can create an anonymous class that implements an interface and this violates direct instantiation of interfaces. Here is an example, using
Code:
ActionListener
, since that's how I use it most.
Code:
  ActionListener listener = new ActionListener () {
    public void actionPerformed (ActionEvent event) {
      //Code here for actionPerformed
    }
  };
I'm not quite sure what else to talk about, let me know if you have any further questions.

MarsChelios
 
MarsChelios

Thank you for your patience, I understand it now.
by creating a variable in this way:

private Set set

it can be reference to any class which implements the set interface giving you more flexibility later on down the road!

Thanks
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top