Overwrite Default Constructor ?

P

Philipp Leitner

hi all,

this may be a silly question, but is there actually any way to
_overwrite_ a constructor of a superclass in Java?

I have the following inheritance structure:

"ProfileAdmin" inherits from "ProfileSearcher"

both classes are almost identical, the main difference is that the
constructor of ProfileSearcher throws an exception in certain
circumstances, while ProfileAdmin should try to repair the problem in
these cases (with the reason that ProfileSearcher should be used on thin
clients, which are not capable of the cpu-heavy repair actions).

My first idea would have been to just overwrite the constructor of
ProfileSearcher, but I quickly discovered that javac inserts an implicit
"super()" at the beginning of the subclasses' constructor (I really had
no clue about that in advance ...) :-(

Any tips on how to solve this issue in a clean way?

thx in advance,
Philipp

--
Philipp Wolfgang Leitner, Bakk.rer.soc.oec.
0225511
Vienna University of Technology

"Ask five economists and you'll get five different explanations (six if
one went to Harvard).
-- Edgar R. Fiedler"
 
T

Thomas Hawtin

Oliver said:
You could have ProfileAdmin catch the exception. But are you sure
ProfileAdmin should be a subclass of ProfileSearcher?

Tricky to catch an exception thrown from a super constructor call...
Perhaps you can add a protected constructor in ProfileSearcher which
"does nothing" (or at least, doesn't throw exceptions), which your
subclasses (e.g. ProfileAdmin) could use.

Yup. I'd go further to suggest making non-leaf classes abstract.

Tom Hawtin
 
O

Oliver Wong

Philipp Leitner said:
hi all,

this may be a silly question, but is there actually any way to _overwrite_
a constructor of a superclass in Java?

Not to my knowledge.
I have the following inheritance structure:

"ProfileAdmin" inherits from "ProfileSearcher"

both classes are almost identical, the main difference is that the
constructor of ProfileSearcher throws an exception in certain
circumstances, while ProfileAdmin should try to repair the problem in
these cases (with the reason that ProfileSearcher should be used on thin
clients, which are not capable of the cpu-heavy repair actions).

You could have ProfileAdmin catch the exception. But are you sure
ProfileAdmin should be a subclass of ProfileSearcher?
My first idea would have been to just overwrite the constructor of
ProfileSearcher, but I quickly discovered that javac inserts an implicit
"super()" at the beginning of the subclasses' constructor (I really had no
clue about that in advance ...) :-(

Any tips on how to solve this issue in a clean way?

Perhaps you can add a protected constructor in ProfileSearcher which
"does nothing" (or at least, doesn't throw exceptions), which your
subclasses (e.g. ProfileAdmin) could use.

- Oliver
 
O

Oliver Wong

Thomas Hawtin said:
Tricky to catch an exception thrown from a super constructor call...

I was aware of the rule that "super()" has to be the first statement,
but I wasn't aware that a "try-catch" block "counts" as a statement. So I
tried the obvious:

<code>
public class Foo {
public Foo() {
try {
super();
} catch (Throwable t) {

}
}
}
</code>

and indeed it doesn't compile.

- Oliver
 
P

Philipp Leitner

well, I tried the same before myself ... and yes, this doesn't compile ...

for now I went with the idea with a "dummy" protected constructor, but I
have to say I don't like the solution much. Perhaps I am really going to
change the inheritance into an aggregation of some kind.

/philipp
 
R

Roedy Green

but I wasn't aware that a "try-catch" block "counts" as a statement. So I
tried the obvious:

To avoid the violating the super comes first rule, you need something
like this:

super( doeseverythingbuteat( parm1 ) );
 
P

Philipp Leitner

To avoid the violating the super comes first rule, you need something
like this:

super( doeseverythingbuteat( parm1 ) );

sorry, I don't get that ;-) How would something like that help me catch
the exception that super() throws?

/philipp
 
P

Patricia Shanahan

Philipp said:
sorry, I don't get that ;-) How would something like that help me catch
the exception that super() throws?

/philipp

It doesn't, but it may help you prevent the exception. In some cases you
could check for the condition that causes the exception, and prevent it
from happening. It is most useful for things like incorrect parameters.

Patricia
 
R

Roedy Green

sorry, I don't get that ;-) How would something like that help me catch
the exception that super() throws?

It wouldn't, but you could do a test to detect the condition that
would upset super and handle it.
 
P

Philipp Leitner

It doesn't, but it may help you prevent the exception. In some cases you
could check for the condition that causes the exception, and prevent it
from happening. It is most useful for things like incorrect parameters.

ok, now I get what you meant; unfortunately this would be quite strange
(if not impossible) to do in my case since I heavily depend on member
variables.

/philipp
 
J

James Of Tucson

Any tips on how to solve this issue in a clean way?

Investigate the "Factory" design pattern.
 
P

Patricia Shanahan

Philipp said:
ok, now I get what you meant; unfortunately this would be quite strange
(if not impossible) to do in my case since I heavily depend on member
variables.

/philipp

Here's another approach. Make the ProfileAdmin constructor private, have
it throw the exception, and supply a static factory method.

The factory method could wrap the attempt to create the object in a
try-catch, and do whatever fix-up it likes on catching the exception.
Make sure the exception carries enough data for the constructor caller
to know what fix-up is needed.

Patricia
 
A

Andrew McDonagh

Philipp said:
well, I tried the same before myself ... and yes, this doesn't compile ...

for now I went with the idea with a "dummy" protected constructor, but I
have to say I don't like the solution much. Perhaps I am really going to
change the inheritance into an aggregation of some kind.

If these classes really do need to be bound in by Inheritance rather
than delegation, then the best approach for your design problem is to
not use public constructors at all.

Instead, use public factory methods on those classes, protected
constructors and move all logic from constructors into init methods.
This way, you can get full control over what happens.

class Base {
protected Base() {
}

protected init(
if (someCondition)
throw new RuntimeException();
}

public static Base createBase() {
Base base = new Base();
base.init();
return base;
}
}

class Derived extends Base {

protected Derived() {
}

protected init() {
try {
super.init();
catch(RuntimeException re) {
system.out.println(re);
}
}

public static Derived createDerived() {
Derived derived = new Derived();
derived.init();
return derived;
}

}
 
A

Andrew McDonagh

Philipp said:
ok, now I get what you meant; unfortunately this would be quite strange
(if not impossible) to do in my case since I heavily depend on member
variables.

/philipp

Its also not a great design choice, because now the derived class would
have knowledge of what is good or bad data from its base class.

You'd never want coupling that is this tight.
 
T

Tony Morris

Philipp Leitner said:
hi all,

this may be a silly question, but is there actually any way to _overwrite_
a constructor of a superclass in Java?

I have the following inheritance structure:

"ProfileAdmin" inherits from "ProfileSearcher"

both classes are almost identical, the main difference is that the
constructor of ProfileSearcher throws an exception in certain
circumstances, while ProfileAdmin should try to repair the problem in
these cases (with the reason that ProfileSearcher should be used on thin
clients, which are not capable of the cpu-heavy repair actions).

My first idea would have been to just overwrite the constructor of
ProfileSearcher, but I quickly discovered that javac inserts an implicit
"super()" at the beginning of the subclasses' constructor (I really had no
clue about that in advance ...) :-(

Any tips on how to solve this issue in a clean way?

thx in advance,
Philipp

--
Philipp Wolfgang Leitner, Bakk.rer.soc.oec.
0225511
Vienna University of Technology

"Ask five economists and you'll get five different explanations (six if
one went to Harvard).
-- Edgar R. Fiedler"

You're referring to, I assume, a no-argument constructor.
This is not the same thing as a default constructor, albeit common
misconception.

You're also experiencing a consequence of the inherent excess requirement
(and subsequent requirment defect) that is implied by the semantics of Java
(and all known OO languages) constructors. Live with it, fix it, or
workaround it.

ContractualJ (http://contractualj.com/):
All constructors are declared private, and throw
java.lang.UnsupportedOperationException, unless they are implicit
constructors of anonymous classes. Exposing construction details (as Java
constructor semantics implies) is not permitted.
 
C

Chris Uppal

Oliver said:
I was aware of the rule that "super()" has to be the first statement,
but I wasn't aware that a "try-catch" block "counts" as a statement.

The idea is that the system doesn't "allow" you to see an object in an
incompletely constructed state[*]. If the super-class's constructor has, in
effect, said "No you can't create this object", then Java and the JVM won't let
a subclass say "Bugger that! I'm going to create it /anyway/".

([*] I agree that the guards against this are a little leaky...)

-- chris
 
C

Chris Smith

Chris Uppal said:
Oliver said:
I was aware of the rule that "super()" has to be the first statement,
but I wasn't aware that a "try-catch" block "counts" as a statement.

The idea is that the system doesn't "allow" you to see an object in an
incompletely constructed state[*]. If the super-class's constructor has, in
effect, said "No you can't create this object", then Java and the JVM won't let
a subclass say "Bugger that! I'm going to create it /anyway/".

Yep, and the problem of course is that a try/catch block is not used
merely to ignore exceptions, but also to wrap them... which may be a
quite sensible thing to want to do.

In this case, though, it appears there's something wrong with the
inheritance structure.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
J

Jeroen V.

You can avoid executing the code in the superconstructor by wrapping the
superconstructor code with:


if(this.getClass().getName().equals(com.xxx.yyy.ProfileSearcher){
//constructor code
}
 
J

Jeroen V.

Jeroen said:
You can avoid executing the code in the superconstructor by wrapping the
superconstructor code with:


if(this.getClass().getName().equals(com.xxx.yyy.ProfileSearcher){
//constructor code
}

should be:

if(this.getClass().getName().equals("xxx.yyy.ProfileSearcher"){
//constructor code
}
 
J

James McGill

should be:

if(this.getClass().getName().equals("xxx.yyy.ProfileSearcher"){
//constructor code
}

How is there a "this" if the superconstructor hasn't been called?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top