Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / March 2007

Tip: Looking for answers? Try searching our database.

Base class - Derived class interaction question

Thread view: 
Daniel - 11 Mar 2007 08:18 GMT
I think my question is best posed by the code:

class Base<Q extends Quantity>{
private int _val = 0;
public Base(int val){
   _val = val;
 }
 public Base<Q> plus(Base<Q> b){
    return new Base<Q>(_val + b._val);
 }
}

class Derived1 extends Base<A> {  //class A extends Quantity
  public Derived1(int val){ super(val);}
}

(I don't believe the generics are relative to my question, but I'm
using them to keep in parallel with my real-world problem.)

I want to be able to do something like the following,
  ...
  Derived1 billy = new Derived1(5);
  Derived1 bob = new Derived1(6);
  Derived1 billyPlusBob = (Derived1)billy.plus(bob);  //
billyPlusBob._val is 11 (if you could access it)
  ...
I understand this is nonsense because the billy.plus call is returning
a reference of type Base<A> which is obviously not type Derived1,
which is why I would get a ClassCastException when trying to cast the
result of billy.plus(bob) to Derived1.

What's stumping me is why I can't figure out how to accomplish the
seemingly trivial task of putting the 'plus' logic in the base class
so that I don't have to implement it in each derived class.  What's
throwing me off is that the plus method has to return a reference of
the _derived_ type, which is seemingly impossible if I'm implementing
the method in the base class.  I'd really, really like to avoid having
to push down the plus method (b/c in reality there are many more
'plus'-like methods and many, many derived classes all of whose logic
is the same), but I absolutely need it to return a reference of the
derived type (or at least one that could be cast to the derived type).

Anybody ever had the same problem?  Any suggestions/insights?
Chrisie - 11 Mar 2007 13:48 GMT
What I'm saying may be complete nonsense but couldn't you write a
static method in each one of the derived classes that takes an object
of the base class and turns it into an object of the derived class? I
guess this is actually a way of working around the problem rather than
solving it but I can't think of any other more intelligent solution.
Patricia Shanahan - 11 Mar 2007 14:57 GMT
> I think my question is best posed by the code:
>
[quoted text clipped - 39 lines]
>
> Anybody ever had the same problem?  Any suggestions/insights?

A high level design comment. If you have a very large number of
different classes that all have the same logic, it is possible that you
are using object class to represent some attribute that might be better
represented in a field or as generic information.

I can see ways of dealing with this using reflection, and a method that
is defined to return a new instance whose class is the same as this with
a specified value. Maybe there is something smoother using generics?

Patricia
Lew - 11 Mar 2007 15:36 GMT
Daniel wrote:
>> I think my question is best posed by the code:
>>
[quoted text clipped - 3 lines]
>>     _val = val;
>>   }

A small side point not pertaining to your main question:

You do not need to initialize _val twice. The initialization to zero is
completely redundant - if you wanted zero Java would've given it to you
without the explicit initialization, but you don't even want zero, you want
the val argument. So don't initialize the member variable to zero.

-- Lew
Chris Uppal - 11 Mar 2007 17:59 GMT
>  What's
> throwing me off is that the plus method has to return a reference of
> the _derived_ type, which is seemingly impossible if I'm implementing
> the method in the base class.

If you think about it you'll see that this is impossible.  You want to do two
incompatible things at once

   - inherit the code from the superclass

   - have that inherited code do something different

There /are/ languages which work like that (where inherited stuff is not merely
inherited but redefined in the subclass), but Java doesn't have the right kind
of type system for that.

The real problem is that the code which creates a new instance does not refer
to the (runtime) class of "this" but the compile-time class where the code is
defined.  Since constructors don't inherit it follows that if you want do this
at all (in Java) you /cannot/ use an explicit constructor in the shared code.
(One more example of how explicit constructors cause fragility.)

Following that thought, the nearest you can get is by refactoring to split the
creation of the new object into something that the subclass can override.  For
instance, you could make use of the built-in clone() operation, like:

   class Base
   implements Cloneable
   {
       Base plus(Base operand)
       {
           // idiotic try/catch elided for clarity
           Base retval = (Base)(this.clone());
           retval.value += operand.value;
           return retval;
       }
   }

And then, in the subclass you can override add() to return a Derived, if you
want:

   class Derived
   extends Base
   {
       Derived plus(Base operand)
       {
           return (Derived)(super.plus(operand));
       }
   }

   -- chris
Daniel - 11 Mar 2007 21:46 GMT
On Mar 11, 9:59 am, "Chris Uppal" <chris.up...@metagnostic.REMOVE-
THIS.org> wrote:
> >  What's
> > throwing me off is that the plus method has to return a reference of
[quoted text clipped - 47 lines]
>
>     -- chris

Thanks for the ideas.  I like the idea of assigning the object
creation to a construct that can pick the appropriate constructor at
runtime (like the clone method) as oppose to to using the constructor,
which, as Chris pointed out, is doomed to use the base class code even
if the calling instance is of derived type.

I would still be interested as to whether there are any design
patterns or generics tricks that I could use to accomplish similar
means without having to change or add any code to the derived classes
at all.  Not an urgent request or anything, just curious (not that it
being urgent would change things from other posters' POVs :-)).

I appreciate everyone's help!

- Daniel
Piotr Kobzda - 12 Mar 2007 09:38 GMT
> Any suggestions/insights?

Try the following:

    abstract class Base<T extends Base<T, Q>, Q extends Quantity> {
        protected int value;

        public Base(int value) {
            this.value = value;
        }

        protected abstract T newInstance(int value);

        public T plus(T b) {
            return newInstance(value + b.value);
        }
    }

    class Derived1 extends Base<Derived1, A> {
        public Derived1(int value) {
            super(value);
        }

        protected Derived1 newInstance(int value) {
            return new Derived1(value);
        }
    }

piotr
Daniel - 13 Mar 2007 02:22 GMT
> > Any suggestions/insights?
>
[quoted text clipped - 25 lines]
>
> piotr

Awesome.  I'm not sure I understand exactly why that works but I know
some good Generics sources I can consult first.  Thanks.


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.