Constructor inheritance

I

isamura

...
: On Tue, 25 Oct 2005 10:37:42 +0100, "Chris Uppal"
: quoted someone who said :
:
: >As far as I know there is no good reason why Java constuctors don't inherit.
:
: How about his case?
:
: Dog( int weightInKg );
:
: Dalmatian( int weightInKg, float percentBlack );
:
: In your universe I would be forced to support a constructor
:
: Dalmatian( int weightInKg );
:
: that would force me to allow Dalmatian objects to be created without
: the Dalmatian colour information.
:
That may well be the case however the inherited constructor is still valid for Dalmatian. One can
over-ride the constructor and provide a default percentBlack value or:

dog = new Dalmatian(20);
dog.percentBlack(0.45);

..K
 
A

Andrew McDonagh

Hendrik said:
Andrew McDonagh schreef:

snipped






Why would you want to use inheritance if it is NOT for an is-a
relationship? That's all inheritance is about.
In Java yes, in OO terms no...

Otherwise, use
delegation. MyClass would not pass Liskov's principle. Anyway, as it
is not a good idea to have public members anyway, I don't see any need
for this (except when by members you also mean methods).

H.


....Inheritance comes in two forms.

1) Interface Inheritance - What you'd expect, this allows Liskov's
Principle. But not necessary code reuse - as in inheriting from a pure
abstract class, or in Java terms, implementing an Interface

2) Implementation Inheritance - What is described above in the C++ code.
The derive class can't be used in terms of Liskov's principle, but it
does have access to all of the base class code and so code re-use in
this form is possible.

In Java we have the choice

1) being very specific about Interface Inheritance - e.g. 'class Blar
implements MyInterface'

2) use Interface & Implementation inheritance at the same time - e.g.
'class Blar extends MyBaseClass'

But we can't have only Implementation inheritance like C++ - and in
general its (even though I miss it sometimes) a very good thing - as it
forces us to 'favor delegation over Inheritance' ( a nice google-able
term there) - which naturally creates a dynamic low coupled design.


Andrew
 
A

Andrew McDonagh

Roedy said:
How about his case?

Dog( int weightInKg );

Dalmatian( int weightInKg, float percentBlack );

In your universe I would be forced to support a constructor

Dalmatian( int weightInKg );

that would force me to allow Dalmatian objects to be created without
the Dalmatian colour information.

No it wouldn't.

The rules governing Virtual constructors is the same for Virtual methods
- over ride if you want/need to.

In your case, if the base class constructor: Dalmatian( int weightInKg )
was called, then the 'percentBlack' member field would be un-initialised
thats all.
 
A

Andrew McDonagh

isamura wrote:

snipped.
:
Can you clarify. Do you mean subclass can't inherit static methods either?

..K

Correct.

Static methods don't belong to an object like normal (aka Instance)
methods, they belong to the Class.

When calling a static method you: 'Class.myStaticMethod()'

there's no object, so no Vtable to use to look through.

Andrew
 
I

isamura

...
: isamura wrote:
:
: snipped.
:
: > :
: > Can you clarify. Do you mean subclass can't inherit static methods either?
: >
: > ..K
: >
: Correct.
:
: Static methods don't belong to an object like normal (aka Instance)
: methods, they belong to the Class.
:
: When calling a static method you: 'Class.myStaticMethod()'
:
: there's no object, so no Vtable to use to look through.
:
This is going off-topic so I will change the thread topic.

That is puzzling since the following compiles and runs (JDK 1.42):

public static myStaticMethod(); // defined in ClassA

ClassB extends ClassA

ClassB.myStaticMethod(); // no problem

Please explain...

..K
 
R

Roedy Green

That may well be the case however the inherited constructor is still valid for Dalmatian. One can
over-ride the constructor and provide a default percentBlack value or:

dog = new Dalmatian(20);
dog.percentBlack(0.45);

However, if you do that you have closed off the ability to demand
values in a compile time check of your constructors.

To turn off the unwanted constructor to you have to get it to throw a
run-time exception.

Constructors bother me because they have so many warts. Sometimes I
say to myself, I wish that new objects were initialised with an
ordinary static method called create. That would make understanding
constructors much easier. But for day to day cranking out code, it
would be tedious.

Note that you could create/initialise all your objects with a static
create method which calls a private noarg empty constructor. But no
one does. Constructors are the cabbage patch dolls of Java -- ugly but
attractive.
 
R

Roedy Green

In your case, if the base class constructor: Dalmatian( int weightInKg )
was called, then the 'percentBlack' member field would be un-initialised
thats all.

That's my complaint. You don't want a security hole like that,
creating invalid Dalmatian objects.
 
R

Roedy Green

: As to why Java's designers came up with the notion of constructors that they
: did; I don't know. My /guess/ is that they were thinking of constructors as
: being "like" static methods -- and they also don't override.
:
Can you clarify. Do you mean subclass can't inherit static methods either?

Constructor are a chimera of static and instance methods. At the JVM
level they behave just like ordinary instance methods. At the language
level they behave much like statics.

First, constructors don't actually create objects (when you look at
the JVM byte code). They just initialise them.

The bodies are much like ordinary instance methods, fooling around
filling in instance fields.

Even though we humans tend to thing of Dog( int weight ) and
Dalmatian( int weight ) as being logically connected, they have
nothing to do with each other at the byte code level. They don't even
have the same name. The only connection is that a wizard in Javac
inserts a call to the corresponding super constructor if you don't
choose one explicitly. At the byte code level, calling a
superconstructor first thing in your constructor is just a convention.
So you can think of constructors as like final instance methods. The
reason they don't inherit is, at the byte code level, there are no
other methods with the same name/signature.
 
R

Roedy Green

ClassB extends ClassA

ClassB.myStaticMethod(); // no problem

at the JVM level, that compiles as invokeStatic ClassA.myStaticMethod.
Allowing you to be sloppy with which level a static came from is just
a convenience of the Java language/javac.
 
I

isamura

...
: On Tue, 25 Oct 2005 17:57:42 -0400, "isamura" <[email protected]>
: wrote, quoted or indirectly quoted someone who said :
:
: >ClassB extends ClassA
: >
: >ClassB.myStaticMethod(); // no problem
:
: at the JVM level, that compiles as invokeStatic ClassA.myStaticMethod.
: Allowing you to be sloppy with which level a static came from is just
: a convenience of the Java language/javac.
:
(Argh!) I was afraid you might say that...another compiler illusion...

This is not a convenience, more like mud-patch which adds more to the confusion of an overly complex
language. I wonder if I should just throw in the towel now.

..K
 
R

Roedy Green

This is not a convenience, more like mud-patch which adds more to the confusion of an overly complex
language. I wonder if I should just throw in the towel now.

The really ugly compiler illusion is myObject.myStaticMethod().

Boy is that confusing! However it has some maintenance advantages.
 
E

Eike Preuss

Roedy said:
The really ugly compiler illusion is myObject.myStaticMethod().
Oh, yes, I agree.
myObject.myStatic() and
ClassBThatExtendsClassA.classAStatic()
are absolutely !§&%!
Boy is that confusing! However it has some maintenance advantages.
Don't state that without explaining :)
It would be nice to know of _any_ justification of the stuff above...

++ Eike
 
R

Roedy Green

Don't state that without explaining :)
It would be nice to know of _any_ justification of the stuff above...

Let say you wrote some code like this

Dog pepe = new Dog( 1.5 /* kg */ );
Dog.register( pepe );

If you wrote that code using the compiler illusion, like this:

Dog pepe = new Dog( 1.5 /* kg */ );
pepe.register( pepe );

Now we add the Chihuahua class, and a new static method that registers
the dog both at city hall and with the Chihuahua association.

I modify the code:
Chihuahua pepe = new Chihuahua( 1.5 /* kg */ );
pepe.register( pepe );

The register method will automatically choose Chihuahua.register if
there is such a thing or Dog.register if there is not. I don't have to
manually maintain it. I only have to specify that pepe is a Chihuahua
in one place.
 
H

Hendrik Maryns

isamura schreef:
...
: On Tue, 25 Oct 2005 10:37:42 +0100, "Chris Uppal"
: quoted someone who said :
:
: >As far as I know there is no good reason why Java constuctors don't inherit.
:
: How about his case?
:
: Dog( int weightInKg );
:
: Dalmatian( int weightInKg, float percentBlack );
:
: In your universe I would be forced to support a constructor
:
: Dalmatian( int weightInKg );
:
: that would force me to allow Dalmatian objects to be created without
: the Dalmatian colour information.
:
That may well be the case however the inherited constructor is still valid for Dalmatian. One can
over-ride the constructor and provide a default percentBlack value or:

dog = new Dalmatian(20);
dog.percentBlack(0.45);
This will only work if you add Dalmatian in front, not if dog is of type
Dog.

But this means you would have to define a method percentBlack which sets
the blackness, and is never used afterwards (I don't suppose the
blackness of a dalmation changes during his lifetime), very bad practice.

H.
--
Hendrik Maryns

==================
www.lieverleven.be
http://aouw.org
 
H

Hendrik Maryns

Andrew McDonagh schreef:
snipped
In Java yes, in OO terms no...

Depends on what you call OO. I'll refine my previous sentence: That's
all inheritance _should be_ about.

...Inheritance comes in two forms.

1) Interface Inheritance - What you'd expect, this allows Liskov's
Principle. But not necessary code reuse - as in inheriting from a pure
abstract class, or in Java terms, implementing an Interface

2) Implementation Inheritance - What is described above in the C++ code.
The derive class can't be used in terms of Liskov's principle, but it
does have access to all of the base class code and so code re-use in
this form is possible.

I'd call this abuse of the inheritance system.
In Java we have the choice

1) being very specific about Interface Inheritance - e.g. 'class Blar
implements MyInterface'

2) use Interface & Implementation inheritance at the same time - e.g.
'class Blar extends MyBaseClass'

But we can't have only Implementation inheritance like C++ - and in
general its (even though I miss it sometimes) a very good thing - as it
forces us to 'favor delegation over Inheritance' ( a nice google-able
term there) - which naturally creates a dynamic low coupled design.

Indeed.
--
Hendrik Maryns

==================
www.lieverleven.be
http://aouw.org
 
H

Hendrik Maryns

isamura schreef:

I think how "often" depends on how inheritance is used. But I will agree sometimes it does involve
new instance variables. In that case, what would the new constructor look like?

ClassB(String s1, String s2) {
super(s1);
this.s2 = s2;
}

or

ClassB(String s1, String s2) {
this.s1 = s1; // s1 instance var is inherited from ClassA - this breaks encapsulation
this.s2 = s2;
}

The first, of course. (Imagine you want something to be done with s1
before it gets assigned. You only have to rewrite your ClassA
constructor, not both. If you only want something to be done with it in
ClassB, you can do super(doSomethingWith(s1)), provided doSomethingWith
is static, or super(s1.someConvenientMethod()), which will always work.
(I'd discourage using the first option).

<snippo>

H.
--
Hendrik Maryns

==================
www.lieverleven.be
http://aouw.org
 
E

Eike Preuss

Roedy said:
Let say you wrote some code like this

Dog pepe = new Dog( 1.5 /* kg */ );
Dog.register( pepe );

If you wrote that code using the compiler illusion, like this:

Dog pepe = new Dog( 1.5 /* kg */ );
pepe.register( pepe );

Now we add the Chihuahua class, and a new static method that registers
the dog both at city hall and with the Chihuahua association.

I modify the code:
Chihuahua pepe = new Chihuahua( 1.5 /* kg */ );
pepe.register( pepe );

The register method will automatically choose Chihuahua.register if
there is such a thing or Dog.register if there is not. I don't have to
manually maintain it. I only have to specify that pepe is a Chihuahua
in one place.
Hm, I see. But doesn't the fact that you would have to manually change
'Dog' to 'Chihuahua' point to a design quirk: That you shouldn't use a
static method but an instance method that can be inherited (and
overwritten)?
So, I'm sorry that myObject.staticMethod() still doesn't make sense to me...

Another question: If the compiler replaces
ClassB.staticDefinedInClassA() by ClassA.staticDefinedInClassA() what is
the point in not inheriting static methods through subclasses??? If you
don't inherit, you can write ClassB.staticDefinedInClassA() but you
won't get the method via reflection of ClassB since
ClassB.class.getMethods() won't return it and
ClassB.class.getDeclaredMethods() neither. You save the method lookup
for static methods, ok, but is there somethings else I'm missing?
 
I

isamura

in message ...
: isamura schreef:
: > "Roedy Green" wrote ...
: > : On Tue, 25 Oct 2005 10:37:42 +0100, "Chris Uppal"
: > : quoted someone who said :
: > :
: > : >As far as I know there is no good reason why Java constuctors don't inherit.
: > :
: > : How about his case?
: > :
: > : Dog( int weightInKg );
: > :
: > : Dalmatian( int weightInKg, float percentBlack );
: > :
: > : In your universe I would be forced to support a constructor
: > :
: > : Dalmatian( int weightInKg );
: > :
: > : that would force me to allow Dalmatian objects to be created without
: > : the Dalmatian colour information.
: > :
: > That may well be the case however the inherited constructor is still valid for Dalmatian. One
can
: > over-ride the constructor and provide a default percentBlack value or:
: >
: > dog = new Dalmatian(20);
: > dog.percentBlack(0.45);
: This will only work if you add Dalmatian in front, not if dog is of type
: Dog.
:
Correct. I wasn't aiming to make the code compile :)

: But this means you would have to define a method percentBlack which sets
: the blackness, and is never used afterwards (I don't suppose the
: blackness of a dalmation changes during his lifetime), very bad practice.
:
Perhaps, but it is never bad practice to provide accessor methods for instance/class variables.

..K
 
T

Tor Iver Wilhelmsen

Andrew McDonagh said:
But we can't have only Implementation inheritance like C++

Yes you can:

public class MyClass {

private OtherClass myOtherClassPart = new OtherClass();

}

MyClass can freely call OtherClass methods (implementation) without
exposing the interface.

The syntax is different, the effect the same.
 
A

Andrew McDonagh

Tor said:
Yes you can:

public class MyClass {

private OtherClass myOtherClassPart = new OtherClass();

}

MyClass can freely call OtherClass methods (implementation) without
exposing the interface.

That's Delegation though, not inheritance.


In the Implementation Inheritance we could have code like:

class OtherClass {
String getName() { return "foo"; }
}


public class MyClass {

private OtherClass myOtherClassPart = new OtherClass();

public String toString() {
return getName(); // <-- call to non-existent method
}

}


When in fact with current Java, this would not compile because MyClass
does not have a method called 'getName()'. So we have to do:

public String toString() {
// we have to delegate to member var.
return myOtherClassPart.getName();
}
 

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,774
Messages
2,569,596
Members
45,128
Latest member
ElwoodPhil
Top