Is this code "proper" use of extend?

C

CJ

Thanks in advance for your responses.

I am relatively new to OOP and though I have muscled my way through
Java, I am still trying to correctly understand the concepts of OO and
how then are modeled into Java.

I am a thirty year procedural language developer, c and assembler, to
this (recent) technology called Object Oriented whatever is somewhat
alien to my experiences. I think I grasp the basic concepts of OO,
that being describing concrete "objects" as a series of refinements to
abstract "conceptual objects." (Please don't flame me if that
statement is incorrect, I am seeking to increase my understanding.)

The following Java 1.5 code I believe demonstrates the statement
above. I needed Vector container that would notify() all active
Objects it contains. My thinking was to simply extend Vector adding
the functionality I wanted.

However, a co-worker is rather irate at me for "doing such a silly
thing," preferring instead to Instantiate a Vector object with
SignaledVector, and implement the entire Vector contract method by
method. That just sounds contrary to principles OO.

Your thoughts?

import java.util.Collection;
import java.util.Vector;

public class SignaledVector<E> extends Vector<E>
{
public SignaledVector()
{
super();
} // public SignaledVector()

public SignaledVector(int initialCapacity)
{
super(initialCapacity);
} // public SignaledVector(int initialCapacity)

public SignaledVector(int initialCapacity,int capacityIncrement)
{
super(initialCapacity,capacityIncrement);
} // public SignaledVector(int initialCapacity,int
capacityIncrement)

public SignaledVector(Collection<? extends E> c)
{
super(c);
} // public SignaledVector(Collection<? extends E> c)

//public synchronized boolean add(E e) { return(super.add(e)); }

/**
* Sends a signal to the object that has posted a {@code
this.wait()}
*
* @param index the index in the element to signal
* @return the component at the specified index
* @throws ArrayIndexOutOfBoundsException
*
*/
public E signal(int index)
throws ArrayIndexOutOfBoundsException
{
E element = get(index);
synchronized(element) { element.notify(); }
return(element);
} // public final void signal<E>(int index)

/**
* Sends a signal to the object that has posted a {@code
this.wait()}
* This method sends a {@code synchronized} signal to all elements
* contained in the {@code SignaledVector}
*
* @throws ArrayIndexOutOfBoundsException
*
*/
public synchronized void signalAll()
throws ArrayIndexOutOfBoundsException,
NullPointerException
{
java.util.Enumeration<E> threads = elements();

while(threads.hasMoreElements())
{
E element = threads.nextElement();
if (null == element) continue;
synchronized(element) { element.notify(); }
} // while(threads.hasMoreElements())
} // public final void signalAll()
} // public class SignaledVector<E> extends Vector<E>

cj
 
J

Joe Attardi

CJ said:
I am relatively new to OOP and though I have muscled my way through
Java, I am still trying to correctly understand the concepts of OO and
how then are modeled into Java.
It's a tough shift in thinking going from procedural to OO, for sure.
It's a fun journey though!
However, a co-worker is rather irate at me for "doing such a silly
thing," preferring instead to Instantiate a Vector object with
SignaledVector, and implement the entire Vector contract method by
method. That just sounds contrary to principles OO.
That is what's known as composition. Sometimes it certainly is a better
fit than inheritance, but in the case of your SignaledVector class you
are making a more specialized version of Vector. Your coworker is wrong
to chastise you for your design choice here, IMHO.

If the intention of SignaledVector is to be a special type of Vector,
which performs all the normal collection related functions of a Vector,
with some extra behavior tacked on (which is how it looks to me), then
you are on the right track!
 
C

CJ

It's a tough shift in thinking going from procedural to OO, for sure.
It's a fun journey though!


That is what's known as composition. Sometimes it certainly is a better
fit than inheritance, but in the case of your SignaledVector class you
are making a more specialized version of Vector. Your coworker is wrong
to chastise you for your design choice here, IMHO.

If the intention of SignaledVector is to be a special type of Vector,
which performs all the normal collection related functions of a Vector,
with some extra behavior tacked on (which is how it looks to me), then
you are on the right track!

Joe, that is exactly my thoughts, creating a specialized "is-a"
Vector.
Thanks.
 
J

Jason Cavett

Joe, that is exactly my thoughts, creating a specialized "is-a"
Vector.
Thanks.

BTW, CJ, you may want to consider using an ArrayList as opposed to a
Vector. If I remember correctly, Vectors are unofficially considered
deprecated. If you want the synchronization of a Vector, look into
the Collections.synchronized* methods.

List<E> list = Collections.synchronizedList(new ArrayList<E>());
 
L

Lew

Jason said:
BTW, CJ, you may want to consider using an ArrayList as opposed to a
Vector. If I remember correctly, Vectors are unofficially considered
deprecated. If you want the synchronization of a Vector, look into
the Collections.synchronized* methods.

List<E> list = Collections.synchronizedList(new ArrayList<E>());

Vector is "deprecated" because it contains legacy non-Collection methods, and
because it has all synchronized methods, forcing you to synchronize whether
you want to or not.

With Java 5, and even more with Java 6, the price of extra synchronization is
much lower, pretty much gone if you don't share the object between threads.
However, ArrayList is the canonical "cleaner" Collection class to use in
preference to Vector. (The other List implementations are also available if
you need their particular characteristics.)
 
C

Curt Welch

CJ said:
Thanks in advance for your responses.

I am relatively new to OOP and though I have muscled my way through
Java, I am still trying to correctly understand the concepts of OO and
how then are modeled into Java.

I am a thirty year procedural language developer, c and assembler, to
this (recent) technology called Object Oriented whatever is somewhat
alien to my experiences. I think I grasp the basic concepts of OO,
that being describing concrete "objects" as a series of refinements to
abstract "conceptual objects." (Please don't flame me if that
statement is incorrect, I am seeking to increase my understanding.)

The following Java 1.5 code I believe demonstrates the statement
above. I needed Vector container that would notify() all active
Objects it contains. My thinking was to simply extend Vector adding
the functionality I wanted.

However, a co-worker is rather irate at me for "doing such a silly
thing," preferring instead to Instantiate a Vector object with
SignaledVector, and implement the entire Vector contract method by
method. That just sounds contrary to principles OO.

Your thoughts?

I agree, it would be very silly to use a has-as relationship and duplicate
the entire vector contract. If you want it to act like a vector, you did
the right thing.

However, I'm not sure if you decision to create an object which acts like a
vector is the right choice. You would have to tell us more about your
application and what you were putting in that vector to allow us to suggest
a different way to fracture your code to solve the problem.

Extending classes you don't have control over can be a risky business.
What happens if the Java guys decide to add a "SignalAll" to the Vector
class? (highly unlikely, but this is just an example). If they not only
added that method in some future release but the Vector would call it's own
signalAll method at times, your version of the method could end up breaking
their code if it didn't happen to do just the right thing.

Using has-a relationships instead of is-a relationships in general is far
safer.

You could have for example made a simple object which held the Vector and
implemented the signal and signalAll methods on the vector as you did, as
well as a getter to get the vector. To use the Vector methods, you just
get the vector from the object and use the Vector methods on the vector
instead of trying to make your object be a vector.

Though in OO terms, you did the right thing based on your description, as a
practical mater of code maintenance, it might have been better to approach
it differently.

On a larger scale, surely there is more you have to do with the objects in
the vector than send these signals to them right? What puts the objects in
the Vector and what takes them out? What type of objects are in the Vector?
In general, when I find I need to do something to a Vector (like perform a
method on every object in the Vector) it would be highly unlikely that I
would end up approaching it like you did and extend the Vector class.

I'm sitting at my car dealer writing this message so let me make up an
example based on that. Lets say I needed to represent the inventory of the
dealer as a collection of cars. And one of the functions I needed to
perform on the collection was to add up the wholesale price of all the
calls to get a total value of the inventory. I could do this like you did
by extending Vector to create a CarVector class and include in that class a
totalWholesaleCost method which would call the wholeSaleCost method of each
car in the Vector and return the sum. But I would not tend to do that.

Instead, I would create a CarDealer Object which had an inventory variable
which was a Vector<Car>. And I would but the totalWholesaleCost method in
the CarDealer object. It's likely the CarDealer object would have other
instance variables as well such as the name of the dealer. There would be
no need to create a special CarVector class to make any of this work just
because there were things I needed to do to the objects in the Vector. So
this is an example of the CarDealer class using the has-a relationship with
the Vector instead of using the is-a relationship.

It's hard to tell whether the has-a relationship might work for you without
understanding more about your application.
 
L

Lew

Curt said:
I agree, it would be very silly to use a has-as relationship and duplicate
the entire vector contract. If you want it to act like a vector, you did
the right thing.

However, I'm not sure if you decision to create an object which acts like a
vector is the right choice. You would have to tell us more about your
application and what you were putting in that vector to allow us to suggest
a different way to fracture your code to solve the problem. ....
It's hard to tell whether the has-a relationship might work for you without
understanding more about your application.

In his superb /Effective Java/, Joshua Bloch has a chapter (Item 14) devoted
to the principle that one should "Favor composition over inheritance", with a
detailed explanation as to why, and when the choice of inheritance is indicated.

Note that when Bloch says, "favor", he doesn't mean, "make a religion out of
insisting on".

<http://www.amazon.com/Effective-Java-Programming-Language-Guide/dp/0321356683/>
 
A

Arne Vajhøj

Lew said:
In his superb /Effective Java/, Joshua Bloch has a chapter (Item 14)
devoted to the principle that one should "Favor composition over
inheritance", with a detailed explanation as to why, and when the choice
of inheritance is indicated.

Yes, but his point does not apply for this case.

If I were to summarize his point with my words it would be: overriding
some methods but not all methods makes the new class dependent
of the implementation instead of just the interface of the old
class because methods may call each other.

But in this case no existing methods are overridden so there
are no problem.

Arne
 
A

Arne Vajhøj

Lew said:
Vector is "deprecated" because it contains legacy non-Collection
methods, and because it has all synchronized methods, forcing you to
synchronize whether you want to or not.

Vector is not deprecated.

ArrayList should be preferred over Vector.

But the term deprecated has a specific meaning in Java and
I think it confuses if it is used in other meanings.

Arne
 
L

Lew

Arne said:
Vector is not deprecated.

ArrayList should be preferred over Vector.

But the term deprecated has a specific meaning in Java and
I think it confuses if it is used in other meanings.

I agree, which is why I put the term in quotes when citing someone else's use
of the term.

However, "deprecated" also has a specific meaning in English, and that meaning
fits the usage quite nicely with respect to java.util.Vector (and Hashtable).

I'm not so sure we can reject normal English outright here.
 
D

Daniel Pitts

Arne said:
Yes, but his point does not apply for this case.

If I were to summarize his point with my words it would be: overriding
some methods but not all methods makes the new class dependent
of the implementation instead of just the interface of the old
class because methods may call each other.

But in this case no existing methods are overridden so there
are no problem.

Arne
If no existing method is overridden, then why have this class extend the
other class at all?
Why not do something like this:
public class SpecialThing {
final List list = new ArrayList();

public List getList() { return list; }

// Do special things here...
}


This doesn't couple your SpecialThing to a particular inheritance
structure, and clearly separates the List operations from the Special
operations.

If SpecialThing should indeed be a "List with more functionality", then
I really do prefer delegation over inheritance. Implement "List", and
delegate to the backing list.

In reality, this is similar to what happens in inheritance anyway, it
just hides what the "parent" class is from those who shouldn't care.

Hmm... Now that I've written this down, I need to spend some time to
consider when its appropriate to use composition vs inheritance... I
know there are really good reasons to use each for certain things, but I
usually use intuition to tell me which...

One feature that I wish Java had would be to "list" methods for
delegation. A special construct:

class Foo implements List {
List myList;
delegates<List.*>() {myList};
}
Or some way to do easy grouping/pattern matching for names. Kind of
like a compile-time proxy. It would help with AOP programming a bit.
 
L

Lew

Arne said:
Yes, but his point does not apply for this case.

Sure it does, at least the part as to "when the choice of inheritance is
indicated."
If I were to summarize his point with my words it would be: overriding
some methods but not all methods makes the new class dependent
of the implementation instead of just the interface of the old
class because methods may call each other.

But in this case no existing methods are overridden so there
are no problem.

So his point applies, on the other side.

The key here is that /Effective Java/ discusses why one would *favor*
composition, and when it's appropriate to use inheritance anyway. You are not
contradicting Mr. Bloch's points as far as I can tell.

Again, he does not espouse blindly applying such a rule when it doesn't make
sense to.
 
A

Arne Vajhøj

Lew said:
I agree, which is why I put the term in quotes when citing someone
else's use of the term.

However, "deprecated" also has a specific meaning in English, and that
meaning fits the usage quite nicely with respect to java.util.Vector
(and Hashtable).

I'm not so sure we can reject normal English outright here.

In this case I think we should.

Vector is "deprecated" but it is not deprecated - does not seem
to me to be a clear message to send.

:)

Arne
 
A

Arne Vajhøj

Daniel said:
>
If no existing method is overridden, then why have this class extend the
other class at all?

It happen that people extend a class without overriding
methods.

I am sure you have seen a couple of examples with JFrame.
Why not do something like this:
public class SpecialThing {
final List list = new ArrayList();

public List getList() { return list; }

// Do special things here...
}

This doesn't couple your SpecialThing to a particular inheritance
structure, and clearly separates the List operations from the Special
operations.

If SpecialThing should indeed be a "List with more functionality", then
I really do prefer delegation over inheritance. Implement "List", and
delegate to the backing list.

The original poster said that it was "with more functionality".

You can delegate. But it result in a lot more code. Sure your IDE can
generate it, but it still clutter up the code base.
In reality, this is similar to what happens in inheritance anyway, it
just hides what the "parent" class is from those who shouldn't care.

It is what happen if no overridden methods. With overridden methods
there are different semantics.

Runtime wise I don't know if the JIT can get rid of the extra
delegation call.

Arne
 
A

Arne Vajhøj

Lew said:
Sure it does, at least the part as to "when the choice of inheritance is
indicated."

Programming is not black magic.

The fact that solution X applied to problem Y is bad does not
imply that solution X is bad to problem Z.
So his point applies, on the other side.

The key here is that /Effective Java/ discusses why one would *favor*
composition, and when it's appropriate to use inheritance anyway. You
are not contradicting Mr. Bloch's points as far as I can tell.

No. His arguments are very valid.

They just don't apply for this case.

Arne
 
D

Daniel Pitts

Arne said:
In this case I think we should.

Vector is "deprecated" but it is not deprecated - does not seem
to me to be a clear message to send.

:)

Arne
Especially since proper English dictates that the non-english meaning
should be quoted.

"Vector is deprecated but it is not 'deprecated'."
I would (and will) specifically say...
Vector *should* be marked deprecated. It is out of date and no longer
standard. Along with Hashtable.
 
J

Joshua Cranmer

Daniel said:
Vector *should* be marked deprecated. It is out of date and no longer
standard. Along with Hashtable.

From what I can tell, the only reason Vector and Hashtable are not
deprecated are that doing so would require too many API changes for
pre-Collections code, and would horribly break backwards compatibility.
(See JTree for example)
 
J

John W. Kennedy

Lew said:
I agree, which is why I put the term in quotes when citing someone
else's use of the term.

However, "deprecated" also has a specific meaning in English,

Yes, it does. "Deprecate" means to pray that God will prevent something
from happening, from Latin "de" ("from") + "precare" ("pray").

Unfortunately, somebody about 75 years ago got the notion it was a
high-falutin' way to pronounce "depreciate", "to lower the value of
something".
 
J

John W. Kennedy

Daniel said:
Vector *should* be marked deprecated.

Not until every existing API demanding Vector and/or Enumerator (such as
SequenceInputStream) has a replacement based on List or Interator.
 
L

Lew

Yes, it does. "Deprecate" means to pray that God will prevent something
from happening, from Latin "de" ("from") + "precare" ("pray").

That definition is indeed listed as an archaic usage.
Unfortunately, somebody about 75 years ago got the notion it was a
high-falutin' way to pronounce "depreciate", "to lower the value of
something".

That definition does not appear. I find "to express disapproval of", "to play
down / belittle, disparage", and "(computing) to discontinue".

<http://en.wiktionary.org/wiki/deprecate>
<http://www.m-w.com/dictionary/deprecate>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top