Java Question: about abstract static stuff and inheritance

statik213

Golden Member
Oct 31, 2004
1,654
0
0
I'm trying to write an abstract class that is dependent on some values to setup various parameters. I want to implement subclasses that set these critical values (amongst other things) that makes the super class construct the object in the required manner.
I can have my sub classes pass these values into the constructor of the base class, but I also want to be able to look at these value statically also.

Let me try and explain what I want to do with a simple example.
Lets say you have an abstract class Polygon and you want to extend it to Rectangle and Triangle.
class Polygon should have these methods:
getName() -- returns the name of the shape, i.e. Rectangle, Triangle
getNumPoints() -- returns the number of points needed to represent one of these polygons.

So I could define polygon like so:

public abstract class Polygon{
String name;
int numPoints;

Polygon(String name, int numPoints){
this.name = name;
this.numPoints = numPoints;
}

String getName(){
return name;
}


String getNumPoints(){
return numPoints;
}
}

Then, define Rectangle and Triangle as:

public class Rectangle extends Polygon{
Rectangle(){
super("Rectangle", 4);
}
}


public class Triangle extends Polygon{
Triangle(){
super("Triangle", 3);
}
}

The code above works for me but does not let me do a getName() and getNumPoints() statically which I should be able to do. Also, having each instance have these class parameters contributes to some memory overhead which I don't mind since I'm not going to have a huge number of these objects around at a time.

I know that I can't have abstract static methods that I could implement in each child class that would return the values I want.

I also need to have a factory that can generate these classes, so I was thinking of passing a unique key (string/int whatever) to the super class that could ask the factory for these parameters based on the unique key. The factory could then return these values statically.

Is there a better solution than this? Know of any good 'design patterns' that may help me out? Any links/resources would be a great help.

Thanks!



 

boran

Golden Member
Jun 17, 2001
1,526
0
76
in general static is bad, the "solution" would be to have these methods statically too, but keep in mind static functions are completely loose from class methods, it's like a static instance of your class which can never be instantiated, and in general static is not that good to use except for singletons or other similar patterns.

I cant help you much farther than that tho, I'm only new to OOP too.
 

statik213

Golden Member
Oct 31, 2004
1,654
0
0
Originally posted by: boran
in general static is bad, the "solution" would be to have these methods statically too, but keep in mind static functions are completely loose from class methods, it's like a static instance of your class which can never be instantiated, and in general static is not that good to use except for singletons or other similar patterns.

I cant help you much farther than that tho, I'm only new to OOP too.

Well that exactly what I an looking for. Look at my exrenely simple example above, think about something where you would have millions of polygon objects around and you'd be unnessarily duplicating two data members which are class specfic and instance specific.

Static makes a lot of sense at some times and I do need it in my hierachy. I could get away without it but it won't be a good implementation and would complicate some other things.
 

boran

Golden Member
Jun 17, 2001
1,526
0
76
well, then my point stays, just write the same method as static. I doubt you can access it trough super then tho, and a static constructor is completely impossible.
 

znaps

Senior member
Jan 15, 2004
414
0
0
Define abstract methods getName and getNumPoints in the Polygon class, and in the subclasses, create private static final fields for name and numPoints, then implement the methods to refer to the static values.
 

kamper

Diamond Member
Mar 18, 2003
5,513
0
0
What znaps said. Having a static getNumPoints() method on the base class makes no sense but having a static, final value in the concrete subclass does make sense.

Just out of curiosity, why would you implement a name property only to have it be exactly the same as the class name? That's a violation of the DRY (don't repeat yourself) principle.
 

statik213

Golden Member
Oct 31, 2004
1,654
0
0
Originally posted by: znaps
Define abstract methods getName and getNumPoints in the Polygon class, and in the subclasses, create private static final fields for name and numPoints, then implement the methods to refer to the static values.

OK, that would solve the memory abuse problem but I'd like getName and getNumPoints also to be static functions which is the whole problem. Ideally i'd be able to define the getName() and getNumPoints() as abstract static, but Java doesn't allow this. Makes sense?
I can sought of see that an 'abstract static' would throws a spanner in the `virtual` function mechanism but I don't understand all the implications of it...
anywayz , thx.... there must be some way of doing this....
 

statik213

Golden Member
Oct 31, 2004
1,654
0
0
Originally posted by: kamper
Just out of curiosity, why would you implement a name property only to have it be exactly the same as the class name? That's a violation of the DRY (don't repeat yourself) principle.

Don't understand what you mean.... What do you mean by a name property?
 

kamper

Diamond Member
Mar 18, 2003
5,513
0
0
The only point of an abstract method is so that you can call it on a base class without knowing what the actual implementation is. Calling Polygon.getNumPoints() makes no sense, you'd have to call Triangle.getNumPoints() or Square.getNumPoints().

Calling polygonInstance.getNumPoints(), however, does make sense because getNumPoints() could be implemented by a subclass. And that, of course, allows for a non-static method.
 

kamper

Diamond Member
Mar 18, 2003
5,513
0
0
Originally posted by: statik213
Originally posted by: kamper
Just out of curiosity, why would you implement a name property only to have it be exactly the same as the class name? That's a violation of the DRY (don't repeat yourself) principle.

Don't understand what you mean.... What do you mean by a name property?
You've defined a method called getName() which implies that every Polygon has a property called "name". The problem is that the value of the name should never be different than the name of the implementing class (or at least that's what I assume you want). Having to type in the name again for every subclass is redundant and the compiler won't catch it if you make a mistake.
 

kamper

Diamond Member
Mar 18, 2003
5,513
0
0
Rather than criticize, though, here's how I'd implement the getName() method in Polygon. No work needed in subclasses.
 

statik213

Golden Member
Oct 31, 2004
1,654
0
0
Originally posted by: kamper
The only point of an abstract method is so that you can call it on a base class without knowing what the actual implementation is. Calling Polygon.getNumPoints() makes no sense, you'd have to call Triangle.getNumPoints() or Square.getNumPoints().

Calling polygonInstance.getNumPoints(), however, does make sense because getNumPoints() could be implemented by a subclass. And that, of course, allows for a non-static method.

Agreed that Polygon.getNumPoints() is non-sensical....
WelI, I had done what znaps and you suggested before I first posted when I came across a few places where it would have been convinient if I could do Triangle.getNumPoints() and Square.getNumPoints() instead of triangleInstance.getNumPoints() and squareInstance.getNumPoints() -- as I didn't want to spawn objects unneccesarily.

I certainly could live w/o this but is there some way of being able to do Triangle.getNumPoints() where getNumPoints has to be implemented on a per-class basis (i.e. abstracted by a super)?




 

kamper

Diamond Member
Mar 18, 2003
5,513
0
0
If you want to call it on a per class basis then it has to be implemented on a per class basis. The compiler will enforce that for you because you can't call the method if it's not there. Again, the only point of having abstract methods is so that you can call them without knowing what class is implementing the call and that doesn't make sense in a static context. Having an abstract static method would be interesting but ultimately it would serve no purpose except to enforce consistency.
 

znaps

Senior member
Jan 15, 2004
414
0
0
Agreed, Abstract methods and Interfaces are for polymorphism, and class (static) methods are totally different. Java has no way of enforcing static implementations on subclasses that I can think of.

Your only other option is a separate utility class with methods like getNumPoints(), getName() etc.
 

statik213

Golden Member
Oct 31, 2004
1,654
0
0
Originally posted by: znaps
Agreed, Abstract methods and Interfaces are for polymorphism, and class (static) methods are totally different. Java has no way of enforcing static implementations on subclasses that I can think of.

Your only other option is a separate utility class with methods like getNumPoints(), getName() etc.

Yeah I did end-up using a utility class with static methods and have the functionality I want.
I define params like `numPoints` and `name` in one place for all my classes, not sure if it is a good implementation/idea though :) (See below)

So now I can do PolygonUtility.getNumPoints("Rectangle") instead of Rectangle.getNumPoints() though longer, it is essentially the same... but a lil more expensive.

Thx all,

 

znaps

Senior member
Jan 15, 2004
414
0
0
Ouch..In getName(), cache the name so you don't go through all that nasty String manipulation every time getName () is called
 

kamper

Diamond Member
Mar 18, 2003
5,513
0
0
That won't work. You're calling getName() (a non-static method) from getNumSides() (a static method).

And on the subject of getName(), you could cache the name if you like but that work is so trivial that unless you're calling it 1000s of times over and over again it's really not a big deal. What I would try, though, is running the code from getName() in the constructor of Polygon to set a final variable (note: you can have an uninitialized final instance variable as long as you set it in the constructor) and just returning that value from the actual getName() method.

Another thing to note on that one though: I wasn't thinking about anonymous or inner classes when I wrote it so you might want to look out for the '$' too. At any rate, it's based on the assumption that a class will always be nicely named so if you wanted to use oddly named classes you might think about overriding the method.
 

statik213

Golden Member
Oct 31, 2004
1,654
0
0
Originally posted by: znaps
Ouch..In getName(), cache the name so you don't go through all that nasty String manipulation every time getName () is called

Yeah, my final implimentation will do that, don't want to clutter the code just yet.

but apart from that, you don't see anything wrong?
 

kamper

Diamond Member
Mar 18, 2003
5,513
0
0
Originally posted by: statik213
but apart from that, you don't see anything wrong?
Other than the fact that it won't compile? ;) (see my last post)
 

statik213

Golden Member
Oct 31, 2004
1,654
0
0
Originally posted by: kamper
Originally posted by: statik213
but apart from that, you don't see anything wrong?
Other than the fact that it won't compile? ;) (see my last post)

What do you mean?

I won't be doing this statically: Rectangle.getNumPoints()
Instead, do this: PolygonUtility.getNumPoints("Rectangle")

So it would work statically, I use the getName() when I want to do instanceOfPolygon.getNumPoints()...

Cool?

 

kamper

Diamond Member
Mar 18, 2003
5,513
0
0
I meant that in the above code you are calling an instance method from a static method, which is not allowed.

Two points concerning PolygonUtility.getNumPoints():
-you can't do a switch on Strings
-I think having the extra utility is bad design. I would just code Rectangle.getNumPoints() and Triangle.getNumPoints()... Unless you need to check dynamically, like you have a String but you don't necessarily know which shape it represents and you just want to pass it to getNumPoints. At that point I might use reflection on the Class itself to call the getNumPoints() method but that's haggling over tiny points.
 

statik213

Golden Member
Oct 31, 2004
1,654
0
0
Yeah, this one:
public static String getNumPoints()
should be:
public String getNumPoints()

And when I want to look at stuff statically I'll be using the PolygonUtility.getNumPoints(className) function, which is basically the same as className.getNumPoints().

Thanks for all the feedback!