Is this code "proper" use of extend?

D

Daniel Pitts

John said:
Not until every existing API demanding Vector and/or Enumerator (such as
SequenceInputStream) has a replacement based on List or Interator.
Actually, the point of deprecation is to allow those API's to be updated
over time because of the knowledge that Vector and Enumerator are going
away soon.

Deprecation is a label saying "Don't use this."
 
C

CJ

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.

To all,

Thank you all for your time spend responding. While the discussion
moved a bit off topic, my understanding of OO has advanced -- forget
the fact of whether my use of Vector as the example is the right
move. I am more interested in the technique, as opposed to the
"history" of Vector.

But Mr Welch noted something which disturbs me about the entire
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.

His statement is true for any base object that get extended, not just
core object of the language. Any object can be "enhanced" -- for lack
of a better word -- and the risk exists the "enhacement" conflicts
with an object extending it. Does not his statement belie the
"benefits" of OO, perhaps highlight a real danger in using OO?

cj
 
J

Joe Attardi

CJ said:
His statement is true for any base object that get extended, not just
core object of the language. Any object can be "enhanced" -- for lack
of a better word -- and the risk exists the "enhacement" conflicts
with an object extending it.

Well, his statement covers "classes you don't have control over". That
can mean a core object of the language or any third party API that you
are using. He does raise an interesting point. There are some API
classes meant to be extended - there are many abstract classes in the
Java API that are obviously meant to be extended.

Extending other classes can be dangerous, per Curt Welch's point. But
IMHO, it is your responsibility, as the author/maintainer of the
subclass, to update your implementation from time to time when the class
it extends changes.

Does that make any sense? I haven't had my coffee yet...
 
C

CJ

Well, his statement covers "classes you don't have control over". That
can mean a core object of the language or any third party API that you
are using. He does raise an interesting point. There are some API
classes meant to be extended - there are many abstract classes in the
Java API that are obviously meant to be extended.

Extending other classes can be dangerous, per Curt Welch's point. But
IMHO, it is your responsibility, as the author/maintainer of the
subclass, to update your implementation from time to time when the class
it extends changes.

Does that make any sense? I haven't had my coffee yet...

Joe, that makes sense. I think even I am getting off topic, this is
after all a Java programming group, not one focused on specific OO
concepts.

Again, thank you all for responding.
 
D

Daniel Pitts

CJ said:
To all,

Thank you all for your time spend responding. While the discussion
moved a bit off topic, my understanding of OO has advanced -- forget
the fact of whether my use of Vector as the example is the right
move. I am more interested in the technique, as opposed to the
"history" of Vector.

But Mr Welch noted something which disturbs me about the entire


His statement is true for any base object that get extended, not just
core object of the language. Any object can be "enhanced" -- for lack
of a better word -- and the risk exists the "enhacement" conflicts
with an object extending it. Does not his statement belie the
"benefits" of OO, perhaps highlight a real danger in using OO?

cj
The true benefit from OO comes when you learn to decouple your system as
completely as possible, without disintegrating it. When you're code
model works well, but you can replace the implementation on any
non-trivial module without breaking the existing implementation of any
other module, you've achieved the "perfect" design.

most designs aren't that perfect, and that's okay. As long as you're
ready to make some changes as other changes happen. Externally managed
modules make it difficult to ensure this rule, as the API may change
over time in incompatible ways.
 
L

Lew

CJ said:
But Mr Welch noted something which disturbs me about the entire


His statement is true for any base object that get extended, not just
core object of the language. Any object can be "enhanced" -- for lack
of a better word -- and the risk exists the "enhacement" conflicts
with an object extending it. Does not his statement belie the
"benefits" of OO, perhaps highlight a real danger in using OO?

You are exactly right. This particular danger is called, "making a class
heritable without planning for the consequences". It's a topic covered very
well, among other places, by Joshua Bloch in his vital /Effective Java/ book.
The problem is that when you make a class heritable, you are exposing much
more of its implementation to other folks, folks who don't know you, folks who
don't have your goals in mind or at heart, folks who can do surprising and
damaging things if you don't lock certain gates.

"I didn't realize that getFoo() could yield a completely different behavior if
its helper method barBaz() was overridden."

The prevention in that particular case is to declare the barBaz() method
'final', i.e., forbidden to be overridden. A well-designed heritable class
locks down behaviors that subclasses should not mess with. It does not call
overridable methods from constructors. It is very close with its access
privileges, rarely straying into package-private, much less protected or
public exposure. It also will change its exposed interface very, very rarely,
if ever. Superclass "enhancements" can break subclass behavior, too.

It seems we programmers just don't get power in a language without the
responsibility to use it wisely.
 
J

John W. Kennedy

Daniel said:
Actually, the point of deprecation is to allow those API's to be updated
over time because of the knowledge that Vector and Enumerator are going
away soon.

Deprecation is a label saying "Don't use this."

Yes, but the Lords of Java should get /their/ APIs straight, first, at
least in the basic packages like java.io.*.

(Of course, the open-source transformation puts a new spin on this.)
 
J

John W. Kennedy

That definition is indeed listed as an archaic usage.

"Archaic" is a grand word to use for something that was current a
century ago and is still employed as a term of art.
That definition does not appear. I find "to express disapproval of",

....which /is/ a form of lowering the value of something.
"to play down / belittle, disparage", and "(computing) to discontinue".

I grant that it is no more possible to repair the
"deprecate"/"depreciate" mess than it is to repair "gentleman" or
"awful", but it's still annoying.
 
L

Lew

"Archaic" is a grand word to use for something that was current a
century ago and is still employed as a term of art.

Take it up with the dictionary writers. I'm not the one who labeled it that.
 
C

Curt Welch

Well, his statement covers "classes you don't have control over". That
can mean a core object of the language or any third party API that you
are using. He does raise an interesting point. There are some API
classes meant to be extended - there are many abstract classes in the
Java API that are obviously meant to be extended.

Extending other classes can be dangerous, per Curt Welch's point. But
IMHO, it is your responsibility, as the author/maintainer of the
subclass, to update your implementation from time to time when the class
it extends changes.

Does that make any sense? I haven't had my coffee yet...

That's true.

The additional risk it creates is that you force the users of your code, to
update there code as well when the third party changes the superclass code.
With inheritance, the users of your code inherent not only your work, but
the work of people who created the superclass - so you expose them to twice
as much potential change than if you use composition and isolate them from
half that change.

I always tend to favor composition over inheritance because it tends to
reduce the dependency between code and reduce future bugs and increase the
ease of future changes. Inheritance is probably the single most important
feature of OO languages, but it should be used with care. It should never
be used just because it's the easy and fast solution to a coding task.
Minimizing current coding time or code length is seldom the prime factor to
consider when making these decisions. Most code worth writing will live a
long life and it is all the future problems you can create or avoid by
making the wrong or right decisions at the start that tend to be the most
important.
 

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,764
Messages
2,569,564
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top