Say I have an abstract class A and 2 subclasses, B and C.
Classes B and C contain a static "type" field that acts as a key to allow
instances of them to be built from details in a DB. Only B and C know what
their own "type" field is to provide encapsulation.
I want a static method in class A that lists all the objects of a type in
the DB i.e.
I call B.listObjects, B inherits the listObjects method from A so the
implementation of this method is only in 1 place.
So, how does A know which type of objects to list? I don't want to have to
duplicate a listObjects method in all the subclasses just to pass a
parameter to the listObjects in A and I don't want to store the type info in
A as that should be encapsulated in the classes it belongs to.
Am I just designing this badly? Having a bit of a mental block!
Cheers for any suggestions.
How about declaring an abstract static getType() method in A, which B and C implement.
Then the A.listObjects() method includes a call to getType() ...
> Say I have an abstract class A and 2 subclasses, B and C.
>
[quoted text clipped - 15 lines]
>
> Cheers for any suggestions.
Bob Arnold - 07 Mar 2004 22:10 GMT
oops ... forgot that Java doesn't allow abstract static methods ...
you'd have to make getType() and listObjects() non-static
> How about declaring an abstract static getType() method in A, which B and C implement.
> Then the A.listObjects() method includes a call to getType() ...
[quoted text clipped - 18 lines]
> >
> > Cheers for any suggestions.
Richard Reynolds - 07 Mar 2004 22:34 GMT
Cheers Bob, that sounds reasonable, I could call this.getType in listObjects
to get the key for that type from the subclass. As you say though,
everything would have to be instance where this really seems like a static
task.
I can't help thinking there must be a design that gets around this!
> oops ... forgot that Java doesn't allow abstract static methods ...
> you'd have to make getType() and listObjects() non-static
[quoted text clipped - 21 lines]
> > >
> > > Cheers for any suggestions.
Shane Mingins - 07 Mar 2004 22:52 GMT
> Cheers Bob, that sounds reasonable, I could call this.getType in listObjects
> to get the key for that type from the subclass. As you say though,
> everything would have to be instance where this really seems like a static
> task.
> I can't help thinking there must be a design that gets around this!
Try posting to comp.object ... you'll prob get some good ideas from there.
If possible I would recommend more contrete examples, IOW what are classes
A, B, C? More domain context can help those reponding if they have a better
picture of your end goal.
Shane
Richard Reynolds - 08 Mar 2004 20:46 GMT
Cheers Shane, will do.
> > Cheers Bob, that sounds reasonable, I could call this.getType in
> listObjects
[quoted text clipped - 9 lines]
>
> Shane
> Say I have an abstract class A and 2 subclasses, B and C.
>
[quoted text clipped - 15 lines]
>
> Cheers for any suggestions.
I have looked at this several times and I still can't see what you are
trying to do. Are you wanting the class, as a static method, to provide a
count of how many times that class has been instantiated? Or how many
objects of that type exist? Because if you are then that is not information
that the class automatically has available. You could incorporate a static
counter to count how many times the class has been instantiated but that
wouldn't tell you how many objects of that type still exist.
More info?
Andrew
--
********************************************************
Andrew Hobbs PhD
MetaSense Pty Ltd - www.metasense.com.au
Australia
61 8 9246 2026
metasens AntiSpam @iinet dot net dot au
*********************************************************
Richard Reynolds - 08 Mar 2004 20:42 GMT
I'll try to explain a little better:
There are different types of objects that can be instantiated from data held
in a DB and you can alter these objects via a web interface.
1: I want to click a link saying "list objects of type x" or "list objects
of type y" which lists the (descriptive) names all of the type x objects in
the DB on a web page.
2: I can select an an individual object from the list which will display a
detailed description of this particular object's fields and allow me to
alter them, the changes to be persisted back to the DB.
These object types are in an inheritance tree all extending a single
abstract base object as I've described below with abstract class A and
subclasses B and C.
It's where to put the method that performs step 1 above I've trouble with.
It's the same implementation for all the subclasses i.e. get the descriptive
names of the objects from the DB where the type is "x", "y" etc. (x or y is
just a DB field that identifies the type of the object and hence how to
build it from the data in the DB, different fields required etc.)
So, as it's the same implementation except, for a "type" parameter, I want
to put this listObjects method in the base class, but the base class
shouldn't need to know the type parameter for every subclass, that should be
encapsulated in each subclass.
That's OK if I want to use this.getType() in the base class method but this
should not be an instance method! It should be a static method as it
pertains to all instances of the class. I should also only have 1 copy of
the type param in each subclass as it too should be a static variable.
Hope that's clearer (but I'm not convinced it is!)
> > Say I have an abstract class A and 2 subclasses, B and C.
> >
[quoted text clipped - 40 lines]
>
> *********************************************************
S Manohar - 09 Mar 2004 00:28 GMT
> > Say I have an abstract class A and 2 subclasses, B and C.
> >
[quoted text clipped - 16 lines]
> >
> > Cheers for any suggestions.
What about using Class:
abstract class A{
/** all objects of all types */
private static Vector allObjects=new Vector();
/** constructor keeps track of all created objects */
public A(){ allObjects.add(this); }
/** Approach 1: filter allObjects for class c */
public static void listObjects(Class c){
Vector result=new Vector();
for(int i=0;i<allObjects.size();i++){
Object o=allObjects.get(i);
if(c.isInstance(o)) result.add(o);
}
return result;
}
/** Approach 2: filter allObjects for this object type */
public void listObjects(){
Vector result=new Vector();
for(int i=0;i<allObjects.size();i++){
Object o=allObjects.get(i);
if(getClass().isInstance(o)) result.add(o);
}
return result;
}
}
class B extends A{}
class C extends A{}
then use
A.listObjects(B.class);
or even
B b=new B();
b.listObjects();
etc.
The alternative method, which would use your TYPE member, would
involve class A to define an abstract method getType() which is
overridden in B and C, and returns your TYPE value. In the
listObjects() method, you could compare the results with the parameter
of the method.
Thanks guys, I think that's enough for me to pick a method.
> Say I have an abstract class A and 2 subclasses, B and C.
>
[quoted text clipped - 15 lines]
>
> Cheers for any suggestions.