abstract class method polymorphically using constructors?

how can i have a method defined in an abstract superclass call a constructor of the actual class running the method?

abstract class A {

public List getMultple() {

List l = new ArrayList();

for (short i=0;i<4;i++) {

l.add(this());//<obviously this breaks

}

return l

}

}

or something like that.A won't run this method, but its children will...and they can call their constructors, but what do i put here to do that?

i've tried a call back.an abstract method getOne() in the superclass forces each child to define that method and in each of those i return the results of a constructor.that works fine.

the problem is i want to abstract this method out of each of these children classes cause its the exact same in each one, just using a different constructor to get multiple of each in a list.so if i use this callback method, then i am not saving the number of methods in each class, so why bother at all?

any ideas?>

[1012 byte] By [arabotha] at [2007-10-2 15:08:46]
# 1
I do not think there is a good OOD way to do this in Java (I won't use the R word). It seems like a pretty wierd need. What are you really trying to do?Drake
Drake_Duna at 2007-7-13 14:02:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 2

we have lots of entities. they each have a getMultiple() static method that lets you get a collection of that entity.. users, documents, whatever..just a standard method we have in each of our entities.i thought it would be nice to pull it out to a superclass, but the constructor is hanging me up.i can do it with reflection, but i'd like to find a non-reflection way of doing it.

even with reflection i need a getClass() call, so it can't be static then.i need to make an object of type X, call its getMultiple()..so thats a wasted object..thats ok for us, but it seems liike i'm just walking around the right way to do this.so i ask....

arabotha at 2007-7-13 14:02:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 3

What is confusing me is the fact that you would need a List full of identical objects. Presumably they are identical, since you don't seem to be passing any parameters.

Anyway, assuming that there is a good reason for it, you may be barking up the wrong tree with trying to abstract this out to a parent class. Maybe what you want is a utility class that can be passed a Class and uses Class.newInstance() to return a List.

Drake

Drake_Duna at 2007-7-13 14:02:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 4

well i can do that this way..thats the reflective way i have it now.

they aren't identical.. i pass in a query to use and the method runs the query against a database returning instances of that object in a List.

it seems like there should be a way.if this(param) was allowed anywhere besides the begining of a constructor, then that would be right.

arabotha at 2007-7-13 14:02:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 5

What do you mean saying "call their constructors"? Do you mean to crate one more instance of the certain class? For what? If you already have an instance to call this method you can use "this" to put it into your list. What about other objects which you want to add to the list? What kind of objects they would be?

SashaPa at 2007-7-13 14:02:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 6

if i have a class "A". i want to be able to call a method getMulitple(String query) that runs a query against a database.each row would then be used to inflate an instance of class "A".each of these i want to put into a List and thats what this method would return.

now that works easily enough. but i have 100's of entities that have this exact method in it. the only exception is each uses its own constructor, passing in the parameters retreived from whatever query was passed in.

i'd like to abstract that method out to a superclass.so, then, if i use a static instance or a real instance of class "A", i can run the method getmultiple(String query) because it is inherited from its superclass.and polymorphically that method knows who is running it, so it seems like i can run that class's constructor passing in the results of the query, however there doesnt seem to be a way to do this in java w/o reflection.

is that right?or is there a way?

arabotha at 2007-7-13 14:02:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 7

I'm still confused. The way to "call a constructor" of another class is to create a new object of that class, using the constructor. If you wrote the class so that the constructor has some useful calculations and you need to do those calculations without creating a new instance, then abstract those calculations out into a separate method -- probably a static method since you don't want a new instance -- or a separate helper class.

But you're right, you're getting hung up on the constructor. If you need to "call a constructor", as I said, then the design of that constructor is wrong.

Besides, talking about classes named "A" is significantly more difficult than talking about classes named "StudentRegistration". Would you like to make it easier for us by explaining the actual problem?

DrClapa at 2007-7-13 14:02:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 8

If the method "getMultple" is implemented as static, then it'll be impossible to know the extending class without external help (seems to me that you don't want that), this is so due to the fact that the static methods are class methods and not instance methods. Well basicly, with only the reference of the abstract class you don't know the extending class.

But, if the method is a non static method then there is a possibility to define an abstract method like : "createInstance" that will force all your extending classes to implement the method and return a new instance avoiding the reflection, or use reflection directly without having to implement the annoyng method....

Don't think that reflection is a bad ideia in this case cause it'll facilitate the maintenance of the code and it's creation, having in mind the extreamly little time of loss of perfornace vs time gained in development.

Conclusion,

as static method is impossible without informing the method of the class that is to be created (by specifying the class).

as non static there are two ways, defining an abstract method like 'createInstance' or using reflection.

Hope it helps,

Daniel Campelo

renkrada at 2007-7-13 14:02:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 9

I still say you are coming at it from the wrong angle. A super class is not the way to go. What you are doing sounds like something very similar to something I did not too long ago.

My requirement was that I had tab delimited text files filed with data that I had to parse. Each line would be used to instantiate one object, so a particular file could be used to instantiate, for example, a thousand objects of the same class. There were different types of files corresponding to different classes to instantiate instances of.

Here is the design I ended up using.

An object of class DataTextFileReader is instantiated to parse the text file and generate objects. It includes code for going line by line, handling bad lines and generating objects and reports. The constructor:

public DataTextFileReader(File inputFile, LineParser<T> theLineParser)

LineParser is an interface with one method:

public T read(String line);

When you call a load() method of the DataTextFileReader, it does its thing with the aid of the LineParser's read method, to which each line is passed, and stores the generated objects in an ArrayList. This can be returned by using another method. There are other methods for getting the reports, etc.

Obviously, the LineParser chosen needs to have code appropriate for parsing the lines in question, so you have to choose and instantiate the right one.

I find this design to work well. I arrived at it after spending hours giving myself headaches trying to come up with a design where there was a superclass roughly equivalent to the DataTextFileReader mentioned above, and classes extending this that fulfilled the duty of the LineParsers mentioned above... rather like what you are trying to do now.

I did not care for the solution at first because it did not give me the "Ah, I am clever!" sensation I was expecting when I finally cracked the problem using inheritance, but I quickly came to think that it was much better OOD anyway.

The LineParsers mentioned above are essentially embodiments of the Factory pattern, and I would recommend you do something similar in your case. Obviously your "constructors" all have to be different, so you should make a separate class for each of those. Then you can put the code that performs the query and loops to create loads of objects in another class called something like DatabaseDepopulator, using appropriate generics as in my example. Really it is the same problem, now that I look at it.

This will also result in better separation of concepts, if you ask me. Why should the class constructor know how to parse a database result query, much less perform the query? It has nothing to do with databases (I presume). That is the job of an interpreter object.

As a final note, remember... 95% of the time you feel like the language won't let you do what you want, it is because you shouldn't anyway.

Drake

Drake_Duna at 2007-7-13 14:02:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 10
By the way, there is also the added concern that if you use reflection do this, you will go to hell when you die.Drake
Drake_Duna at 2007-7-13 14:02:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 11

> if i have a class "A". i want to be able to call a

> method getMulitple(String query) that runs a query

> against a database.each row would then be used to

> inflate an instance of class "A".each of these i

> want to put into a List and thats what this method

> would return.

>

Doesn't sound like a good idea to me.

Your functionality looks like this.

1. List of queries.

2. Create instance based on result of each query.

2.A Populate instance using data in query.

3. Put instance into collection

4. Return collection.

The above looks like more than one class to me. Step 2.A is the only thing that your current class should be doing.

jschella at 2007-7-13 14:02:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 12

it doesnt have to be a database query..i can pass in a collection of random numbers and i want to construct instances of class "FooBar" from those numbers. they can be statistics...ignore the database stuff thats not relavent.

as far as a couple of you guys have mentioned: use an outside method like getInstance().why not just keep the getMultiple() then in each entity class? i haven't saved anything with this method.at least with the reflective design i can go w/o adding another method in each entity class.

as far as taking the getmultiple() funcationality out into a factory class, i don't think thats as good as letting the one class implement this getMultiple() feature.now that its defined in a single place, i don't need factories for each entity type. i like less code, not more.

arabotha at 2007-7-13 14:02:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 13

>Besides, talking about classes named "A" is significantly more

>difficult than talking about classes named "StudentRegistration".

> Would you like to make it easier for us by explaining the actual

> problem?

they are 100's of entitys, each doing their own thing.so lets say:

StudentEntity

TeacherEntity

HomeworkEntity

SchoolEntity

RandomIntEntity

lets say studententity and teacherentity are instantiated from a database. homework comes from an RSS feed, and school comes from a webservice call.and the randomIntentity works like the random int stuff built into java--> passing in a seed gets you a 'random' number. each of their constructor's know what to do as far as making an object.now i need factories for each of these things.currently we have a getMultiple() method that does the same thing for each type. its currently implemented in each class, the only difference being each class calls "new" for its type, so they aren't immediately compatible.for example, the studententity calls "new StudentEntity(whatever)" and the homeworkentity calls "new homeworkentity(whatever)".

so, i'd like to pull that getMultiple(whatever) method out to the superclass of these classes.i've been able to do it in the past using an extra getInstance() method that was required by the abstract superclass, and with reflection.the reflection method lets me keep the getMultiple() up at the superclass and no trace of it is in the children classes, but its using reflection, so i don't much like that as a final solution.

i want to avoid using a factory class for each entity because i dont think its needed for this case when the getMultiple() seems to be exactly right and has less footprint.the getisntance(0 method is better OODA, but i could just leave the getMutliple() in their current spots in each entity class and it would all work the same.i could have the abstract superclass just require everyone to implement a getMultiple and i'd be attacking the problem more directly (thus more clear, etc etc)

arabotha at 2007-7-13 14:02:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 14
I belive that using getInstance() is a right decision. One day if you want to change a constructor for one of your classes this will help you very much.
SashaPa at 2007-7-13 14:02:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 15

> it doesnt have to be a database query..i can

> pass in a collection of random numbers and i want to

> construct instances of class "FooBar" from those

> numbers. they can be statistics...ignore the

> database stuff thats not relavent.

Doesn't matter.

You still have a class that (presumably does something).

You have other functionality that is used to create more than one instance of the class (or children.)

The description above does not generally fall into two classes unless

1. The functionality is VERY simple

2. The class that is being built is VERY simple

3. It is known that neither 1 nor 2 will ever become complicated.

> as far as taking the getmultiple() funcationality out

> into a factory class, i don't think thats as good as

> letting the one class implement this getMultiple()

> feature.now that its defined in a single place, i

> don't need factories for each entity type. i like

> less code, not more.

One doesn't use OO solely or even principally because it requires less code. If one creates a good design with OO than it is going to take less code than if one creates a bad design. That doesn't mean that the good OO design is going to the absolute minimum number of lines of code to implement the functionality.

Software engineering takes into account not only what one needs to do today but what one knows that will be needed to be done tomorrow. And the second doesn't lead to the fewest lines of code.

jschella at 2007-7-20 22:28:52 > top of Java-index,Other Topics,Patterns & OO Design...
# 16
in this case, these classes will stay simple forever. and less code will be better for us.
arabotha at 2007-7-20 22:28:52 > top of Java-index,Other Topics,Patterns & OO Design...
# 17
> in this case, these classes will stay simple forever.> and less code will be better for us.Ok. But to be clear, if it is in fact using database queries then it doesn't fall into my definition of what very simple means.
jschella at 2007-7-20 22:28:52 > top of Java-index,Other Topics,Patterns & OO Design...