Constructors and Super

I wrote a class and a subclass - both immutable.

The superclass only has one constructor and the subclass

also has one constructor (though it is different than the

superclass).

I need for the subclass constructor to take some

numbers, perform some operations and call the the

constructor of the superclass.

Of course this wont work because super() has to be the first call.

Also, this subclass should only have this ONE constructor.

How should i resolve this problem?

These are all the options I can see:

- Dont make the classes immutable

That seems drastic.

- Add the subclasses constructor to the superclass

Moving behavior to an unrelated class seems bad.

- Using a static method that creates the object

Seems like my only real option but then how do i stop people

from instantiating the class (using the superclass' constructor)?

[947 byte] By [TuringPesta] at [2007-11-26 17:07:19]
# 1

> - Using a static method that creates the object

> Seems like my only real option

Based on:

"I need for the subclass constructor to take some

numbers, perform some operations and call the the

constructor of the superclass."

I would agree.

>but then how do i stop

> people

> from instantiating the class (using the superclass'

> constructor)?

Maybe make the superclass constructor protected?

zadoka at 2007-7-8 23:35:08 > top of Java-index,Java Essentials,Java Programming...
# 2
> - Using a static method that creates the object> Seems like my only real option but then how do i stop> people> from instantiating the class (using the superclass'> constructor)?Make the superclass constructor package private.
kajbja at 2007-7-8 23:35:08 > top of Java-index,Java Essentials,Java Programming...
# 3

> Of course this wont work because super() has to be the first call.

Disregarding the design implications, you can get around this in a semi-sneaky manner:

class Foo {

private int i;

Foo(int i) {

this.i = i;

}

}

class Bar extends Foo {

Bar(int x, int y) {

super(someComplexCalculations(x, y)); // < aha.

}

private static int someComplexCalculations(int x, int y) {

// ...

return 0;

}

}

~

yawmarka at 2007-7-8 23:35:09 > top of Java-index,Java Essentials,Java Programming...
# 4
@Op. What type of calculations? Are they advanced? Can't they be made in the call to super?
kajbja at 2007-7-8 23:35:09 > top of Java-index,Java Essentials,Java Programming...
# 5

Thanks for all your ideas and help.

> super(someComplexCalculations(x, y)); // < aha.

Haha. If that works that is awesome.

The calculations are simple and couldve have actually been

done within the super( calc, calc ) call except for a necessary

b@stard if statement that ruins the whole thing, lol.

if(boolean){

super(regular);

} else {

super( calculations );

}

Im ok with a factory design (thats what it is right?) and making a

static creator and making the super constructor private.

This is making my first forray into immutability unpleasant.

TuringPesta at 2007-7-8 23:35:09 > top of Java-index,Java Essentials,Java Programming...
# 6
I was already warned not to get "creative" with this design, lol.
TuringPesta at 2007-7-8 23:35:09 > top of Java-index,Java Essentials,Java Programming...
# 7
> Haha. If that works that is awesome.I wouldn't post it if it didn't... ;o)~
yawmarka at 2007-7-8 23:35:09 > top of Java-index,Java Essentials,Java Programming...
# 8
> if(boolean){> super(regular);> } else {> super( calculations );> }This does also worksuper(boolean ? regular : calculations);
kajbja at 2007-7-8 23:35:09 > top of Java-index,Java Essentials,Java Programming...
# 9

super(boolean ? regular : calculations);

That would be acceptable except the super constructor is

(float, float). I could add a constructor that takes an array

but is there a way guarentee an array size in a constructor or

method?

As in:

some Method(array[of only size 2]){ }

Maybe have the constructor throw an error if the array size is of?

TuringPesta at 2007-7-8 23:35:09 > top of Java-index,Java Essentials,Java Programming...
# 10

It's kinda hack-ish, but I would use a simple struct type of class long before I ever used an array:

class ParamSet {

public float width = 0;

public float height = 0;

}

class A {

private A(float area) {

this.area = area;

}

}

class B {

public B(ParamSet params) {

super(computeArea(params));

}

private static float computeArea(ParamSet params) {

return (params.width * params.length);

}

}

There's really no reason to group the width and length like this, so this analogy is a terrible example.

Message was edited by:

kevjava (he did say floats)

kevjavaa at 2007-7-8 23:35:09 > top of Java-index,Java Essentials,Java Programming...
# 11
Haha, thats funny because the subclass in my example isactually the sub of a struct class, lol.So i couldnt have a struct class to hold the couple values thesuperclass exists to hold. Youre right though, in other situations that would be better.
TuringPesta at 2007-7-8 23:35:09 > top of Java-index,Java Essentials,Java Programming...
# 12

How would I chain classes that only had a static method to

instantiate them?

public Class1{

private Class1(...){}

static Class1 create(...){}

}

public Class2 extends Class1{

private Class2(...){}

static Class2 create(...){}

}

It seems that this wouldnt be possible. Class1 is unsubclassable

right? Protected allows access from anywhere in the package and

that is way too much access.

TuringPesta at 2007-7-8 23:35:09 > top of Java-index,Java Essentials,Java Programming...
# 13

> Protected allows access from anywhere in the package and

> that is way too much access.

Perhaps inheritance is not a good design decision in your case; it sounds like composition may be a better choice. If your class actually needs to be extended, you should design it to do so. Otherwise, prevent it.

Anyway, what risk do you perceive in having package access to the superclass constructor?

~

yawmarka at 2007-7-8 23:35:09 > top of Java-index,Java Essentials,Java Programming...
# 14

> Anyway, what risk do you perceive in having package access to the superclass constructor?

I cant use composition though that was a good idea previously

brought up.

Im still trying to fix this super() problem.

class BaseClass{

// Immutable

public BaseClass(val1, val2){}

}

// This is not possible

class SubClass1 extends BaseClass{

public SubClass1(val1, val2, val3){

// calculations

super(val1, val2);

}

}

// So if this...

class SubClass1 extends BaseClass{

private SubClass1(val1, val2){

super(val1, val2);

}

public static SubClass1 create(val1, val2, val3){

// calculation

return new SubClass1(val1, val2);

}

}

// Now cant do this

class SubClass2 extends SubClass1{

// F'd real good

}

TuringPesta at 2007-7-8 23:35:09 > top of Java-index,Java Essentials,Java Programming...
# 15

> I cant use composition...

I don't believe that. Why can't you use composition? Why do you think you need to extend the immutable class?

Until you provide some substantial justification or a reasonable context around the problem, you're not likely to get much in the way of useful help. Rather, you're likely to get responses like mine; i.e., your design is wrong. As mentioned before, either design for inheritance or prevent it. Either your "immutable" superclass should be designed to be extended, or you should forget about inheritance (what extended functionality is the subclass offering, anyway?) and simply construct an appropriate instance of the superclass based on some condition.

You may also want to see reply #3 again, but I still question the need for your proposed design.

~

yawmarka at 2007-7-21 16:57:55 > top of Java-index,Java Essentials,Java Programming...
# 16

The 3 classes have to be interchangable in the code.

I suppose I could create an interface to make them all

interchangable.

But now im making an interface and creating twice as many objects

(for every composed class i know am instantiating that class and the

reference to other classes).

It doesnt seem elegant (not that ive found anything elegant) for

3 classes that are conceptual extensions of each other.

All i want to do is make one calculation before the call to super(...), lol,

and there wouldnt be any need for all this.

Im just going to add the one calculation to the superclass.

Its not worth all this for one if statement and a single calculation.

TuringPesta at 2007-7-21 16:57:56 > top of Java-index,Java Essentials,Java Programming...
# 17

> The 3 classes have to be interchangable in the code.

Why? Why do you need three classes?

> I suppose I could create an interface to make them

> all interchangable.

I don't see why you would choose that route, either.

> But now im making an interface and creating twice as many objects

> (for every composed class i know am instantiating that class and the

> reference to other classes).

> It doesnt seem elegant (not that ive found anything elegant) for

> 3 classes that are conceptual extensions of each other.

It doesn't sound elegant to me, either. But I think that's because you're approaching your design from a single point of view, and you haven't provided any context from which others with perhaps more experience may make a recommendation for a design that actually *is* elegant.

> All i want to do is make one calculation before the

> call to super(...), lol,

See reply #3.

> and there wouldnt be any need for all this.

There has been no evidence that you need any of "this" anyway... :o)

Unfortunately, without any reasonable context, there's not much else I'm able to help with. Best of luck!

~

yawmarka at 2007-7-21 16:57:56 > top of Java-index,Java Essentials,Java Programming...
# 18
Thank god for the ternary operator. I was able to make a very ugly:super( bool ? val1 : calculation(), bool ? val1 : calculation() ..... );Now everything can be public, no statics, no factorys, no problems.
TuringPesta at 2007-7-21 16:57:56 > top of Java-index,Java Essentials,Java Programming...
# 19
> Thank god for the ternary operator. I was able to> make a very ugly:If that's your preference... *shrugs*~
yawmarka at 2007-7-21 16:57:56 > top of Java-index,Java Essentials,Java Programming...
# 20

> All i want to do is make one calculation before the

> call to super(...), lol,

> See reply #3.

Yea I hit a nonexistent roadblock when I first read that.

I was trying to do the whole thing in one method call - and therefore

needing an array but I didnt want to create a constructor that

took an array. Never once did it occur to me to call the method

X number of times. Which is essentially what the ternary is doing -

in fact ill probably replace it with a method.

TuringPesta at 2007-7-21 16:57:56 > top of Java-index,Java Essentials,Java Programming...
# 21

Out of curiosity, why haven't you answered any of my questions? I didn't intend them to be interpreted rhetorically.

- What risk do you perceive in having package access to the superclass constructor?

- Why can't you use composition?

- Why do you think you need to extend the immutable class?

- What extended functionality is the subclass offering?

- Why do you need three [interchangeable] classes?

~

yawmarka at 2007-7-21 16:57:56 > top of Java-index,Java Essentials,Java Programming...
# 22

> Out of curiosity, why haven't you answered any of my questions? I didn't intend them to be interpreted rhetorically.

Easy Killer. I didnt intentionally not answer your questions. I thought

I had in part answered most.

- What risk do you perceive in having package access to the superclass constructor?

I really disliked the whole private constructors with static initializer

solution and was trying to find a solution without doing that. The

package access question is only relevant if im using that solution

which is why I didnt dwell on this. I didnt want the risk of other

programmers creating classes in this package that could break

the immutability of the 3 classes or getting around the factory setup.

- Why can't you use composition?

Because the 3 classes should be interchangeable. See below.

Like I said I could still use composition if the 3 classes implemented a

common interface.

1- Why do you think you need to extend the immutable class?

2- What extended functionality is the subclass offering?

3- Why do you need three [interchangeable] classes?

The base immutable class is a data struct that holds some values (just a few results from computations). These values should never be changed. I am writing a library that does computations on the values

in this class.

1 subclass holds additional computed information (about twice as much) that is sometimes needed. Now these lengthy computations

dont have to be recalculated every time theyre needed.

As there are thousands of these objects it is needless in many cases

to have this information stored in the base class.

The 2nd subclass isnt really as important and is actually a special case

of the 1st subclass which guarentees a certain state - the values

are in a certain useful set.

The library performs using the values in the base class.

It would be wasteful to write every computation for a case of each class.

TuringPesta at 2007-7-21 16:57:56 > top of Java-index,Java Essentials,Java Programming...