why is var superValue not getting initialized to 911 in this code

A

ankur

I was little confused as to how the this reference works in this case.
I thought that the this reference in SuperClassA constructor would
call the doValue() in superclass A.

package pack4;
class SuperclassA {
protected int superValue; // (1)
SuperclassA() { // (2)
System.out.println("Constructor in SuperclassA");
this.doValue(); // (3)
}
void doValue() { // (4)
this.superValue = 911;
System.out.println("superValue: " + this.superValue);
}
}

class SubclassB extends SuperclassA {
private int value = 800; // (5)
SubclassB() { // (6)
super();
System.out.println("Constructor in SubclassB");
this.doValue();
System.out.println("superValue: " + this.superValue);
}
void doValue() { // (7)
System.out.println("value: " + this.value);
}
}

public class ObjectInitialization {
public static void main(String[] args) {
System.out.println("Creating an object of SubclassB.");
new SubclassB(); // (8)
}
}

Output :

Creating an object of SubclassB.
Constructor in SuperclassA
value: 0
Constructor in SubclassB
value: 800
superValue: 0

Thanks,
Ankur
 
A

Arne Vajhøj

ankur said:
I was little confused as to how the this reference works in this case.
I thought that the this reference in SuperClassA constructor would
call the doValue() in superclass A.

package pack4;
class SuperclassA {
protected int superValue; // (1)
SuperclassA() { // (2)
System.out.println("Constructor in SuperclassA");
this.doValue(); // (3)
}
void doValue() { // (4)
this.superValue = 911;
System.out.println("superValue: " + this.superValue);
}
}

class SubclassB extends SuperclassA {
private int value = 800; // (5)
SubclassB() { // (6)
super();
System.out.println("Constructor in SubclassB");
this.doValue();
System.out.println("superValue: " + this.superValue);
}
void doValue() { // (7)
System.out.println("value: " + this.value);
}
}

public class ObjectInitialization {
public static void main(String[] args) {
System.out.println("Creating an object of SubclassB.");
new SubclassB(); // (8)
}
}

Output :

Creating an object of SubclassB.
Constructor in SuperclassA
value: 0
Constructor in SubclassB
value: 800
superValue: 0

All methods are virtual in Java.

But calling a method like this in a constructor is a big no no.

Arne
 
M

Mark Space

ankur said:
I was little confused as to how the this reference works in this case.
I thought that the this reference in SuperClassA constructor would
call the doValue() in superclass A.

package pack4;
class SuperclassA {
protected int superValue; // (1)
SuperclassA() { // (2)
System.out.println("Constructor in SuperclassA");
this.doValue(); // (3)
}
void doValue() { // (4)
this.superValue = 911;
System.out.println("superValue: " + this.superValue);
}
}

class SubclassB extends SuperclassA {
private int value = 800; // (5)
SubclassB() { // (6)
super();
System.out.println("Constructor in SubclassB");
this.doValue();
System.out.println("superValue: " + this.superValue);
}
void doValue() { // (7)
System.out.println("value: " + this.value);
}
}

public class ObjectInitialization {
public static void main(String[] args) {
System.out.println("Creating an object of SubclassB.");
new SubclassB(); // (8)
}
}

Output :

Creating an object of SubclassB.
Constructor in SuperclassA
value: 0
Constructor in SubclassB
value: 800
superValue: 0

Thanks,
Ankur
 
M

Mark Space

(Sorry about the previous post, pilot error.)
I was little confused as to how the this reference works in this case.
I thought that the this reference in SuperClassA constructor would
call the doValue() in superclass A.


"this" refers to the object, not the class. Since doValue() is
overloaded by SubclassB, when you create that object, it is SubclassB's
doValue() that gets called.

As Arne said, calling a method that can be overloaded from a constructor
is a very bad idea. It will get you all sorts of trouble.

Two suggestions: 1. Make doValue "final". Then it cannot be overloaded
by SubclassB, although SubclassB's doValue method will be illegal. 2.
Make doValue "private". Then it still cannot be overloaded by
SubclassB, although it can't be seen by any classes either.
 
J

Joshua Cranmer

ankur said:
I was little confused as to how the this reference works in this case.
I thought that the this reference in SuperClassA constructor would
call the doValue() in superclass A.

Nope. All method calls (except calls to private methods or calls via
|super|) are virtual method calls. The value of |this| does not change
between super/subclasses. It doesn't matter if you're in a constructor
or somewhere else.

Note that for this reason, and the additional requirements on order of
class initialization, it is extremely, extremely bad to call any
non-private or non-final method in a constructor of a non-final class.
It is indeed bad to let |this| escape a constructor in any circumstance
except under certain, carefully controlled circumstances
(java.util.Random is a notable class that fails this requirement badly).
 
L

Lew

Mark said:
Two suggestions: 1. Make doValue "final". Then it cannot be overloaded
overridden

by SubclassB, although SubclassB's doValue method will be illegal. 2.
Make doValue "private". Then it still cannot be overloaded by

overridden by
 
L

Lew

Joshua said:
Nope. All method calls (except calls to private methods or calls via
|super|) are virtual method calls. The value of |this| does not change
between super/subclasses. It doesn't matter if you're in a constructor
or somewhere else.

If the subclass were in a different package, then there would not be an
override in the example because 'doValue()' has package-private access there.
 
A

ankur

If the subclass were in a different package, then there would not be an
override in the example because 'doValue()' has package-private access there.

Lew, you are right ..again ! So what would 'doValue()' of SubclassB be
doing in this case ? Whats the technical term for that, because it is
definitely not overriding ( and neither overloading, hiding ,
shadowing or obscuring) ?
 
L

Lew

(citation restored)
Lew, you are right ..again ! So what would 'doValue()' of SubclassB be
doing in this case ? Whats the technical term for that, because it is
definitely not overriding ( and neither overloading, hiding ,
shadowing or obscuring) ?

None of the above. It's just a new method.
 
L

Lew

ankur said:
hmmm , i [sic] c. wow. Lets coin a term, write to sun [sic] and get it included in
the JLS !

That doesn't seem necessary. The superclass package-private method is
invisible to a subclass method from a different package, so from the subclass
point of view it doesn't exist, in that respect being just like a private
method.

What do you call hiding something that doesn't exist?
 
A

ankur

ankur said:
hmmm , i [sic] c. wow. Lets coin a term, write to sun [sic] and get it included in
the JLS !

That doesn't seem necessary.  The superclass package-private method is
invisible to a subclass method from a different package, so from the subclass
point of view it doesn't exist, in that respect being just like a private
method.

What do you call hiding something that doesn't exist?

In this particular scenario when I declare a method in the subclass
with the same signature in the superclass, java gives me warning that"
the method does not override the inherited method from superclass
etc...". Moreover the method cannot be used if declared this way to
exhibit polymorphic behavior. All I am saying is that there needs to
be a term to describe this kind of behavior ( or rather a pitfall on
part of programmer).
 
L

Lew

ankur said:
In this particular scenario when I declare a method in the subclass
with the same signature in the superclass, java [sic] gives me warning that"
the method does not override the inherited method from superclass etc...".

Huh? I get no such warning.

Are you certain that this is a warning when you declare a package-private
method in the subclass that matches the signature of a parent-class
package-private method, where child and parent are in different packages?

Please post a *complete* example and the *exact*, *complete* compiler message.

<example class="testit.Parent">
package testit;

/** Parent. */
public class Parent
{
/* p-p */ void packard()
{
System.out.println( "Super.packard()" );
}
}
</example>

<example class="testit.other.OtherOffspring">
package testit.other;

import testit.Parent;

/** OtherOffspring. */
public class OtherOffspring extends Parent
{
/* p-p */ void packard()
{
System.out.println( "Offspring.packard()" );
}
}
</example>

Compiles without warning or error for me.
Moreover the method cannot be used if declared this way to
exhibit polymorphic behavior. All I am saying is that there needs to
be a term to describe this kind of behavior ( or rather a pitfall on
part of programmer).

I disagree. If a method is invisible to the child class, then there is no
method to override or hide. About the only term that makes sense is that the
child class has a "non-overriding method", hardly distinguishing as it is the
normal case that methods do not override.

What would you call such a method, that does not hide, override, overload or
otherwise interact with a parent-class method, other than simply "a method"?
 
A

ankur

ankur said:
In this particular scenario when I declare a method in the subclass
with the same signature in the superclass, java [sic] gives me warning that"
the method does not override the inherited method from superclass etc....".

Huh?  I get no such warning.

Are you certain that this is a warning when you declare a package-private
method in the subclass that matches the signature of a parent-class
package-private method, where child and parent are in different packages?

Please post a *complete* example and the *exact*, *complete* compiler message.

<example class="testit.Parent">
package testit;

/** Parent. */
public class Parent
{
     /* p-p */ void packard()
     {
         System.out.println( "Super.packard()" );
     }}

</example>

<example class="testit.other.OtherOffspring">
package testit.other;

import testit.Parent;

/** OtherOffspring. */
public class OtherOffspring extends Parent
{
     /* p-p */ void packard()
     {
         System.out.println( "Offspring.packard()" );
     }}

</example>

Compiles without warning or error for me.
Moreover the method cannot be used if declared this way to
exhibit polymorphic behavior. All I am saying is that there needs to
be a term to describe this kind of behavior ( or rather a pitfall on
part of programmer).

I disagree.  If a method is invisible to the child class, then there is no
method to override or hide.  About the only term that makes sense is that the
child class has a "non-overriding method", hardly distinguishing as it is the
normal case that methods do not override.

What would you call such a method, that does not hide, override, overload or
otherwise interact with a parent-class method, other than simply "a method"?

I use eclipse and here's what I observed.
I moved SuperclassA and ObjectInitialization in same package and
moved SubclassB to a new package. I kept the package accessibility for
doValue() in both super class and sub class. I for a warning right
next to the doValue in SubclassB that "the method does not override
the inherited method from superclass etc...". Its the exact same code
that I posted earlier but I just moved the classes to new packages. Of
course I had to make SubclassB and SuperclassA public as I used
separate .java files for them.
 
L

Lew

ankur said:
I use eclipse [sic] and here's what I observed.
I moved SuperclassA and ObjectInitialization in same package and
moved SubclassB to a new package. I kept the package accessibility for
doValue() in both super class and sub class. I for a warning right
next to the doValue in SubclassB that "the method does not override
the inherited method from superclass etc...".

That really does not look like an exact quote of the warning. Did it really
say "etc...." like that, with no preceding comma and four periods?

Are you also saying that this was an Eclipse warning, not a Java warning?
That would explain why I got no warning whatsoever from javac when I compiled
my example.

Interesting that Eclipse would give a warning for perfectly valid Java code.
Lets coin a term, write to sun [sic]
and get it included in the JLS !

I don't think it makes much sense for the Java language to change itself to
accommodate an IDE-specific feature.
 
A

Arne Vajhøj

Lew said:
ankur said:
I use eclipse [sic] and here's what I observed.
I moved SuperclassA and ObjectInitialization in same package and
moved SubclassB to a new package. I kept the package accessibility for
doValue() in both super class and sub class. I for a warning right
next to the doValue in SubclassB that "the method does not override
the inherited method from superclass etc...".

That really does not look like an exact quote of the warning. Did it
really say "etc...." like that, with no preceding comma and four periods?

Are you also saying that this was an Eclipse warning, not a Java
warning? That would explain why I got no warning whatsoever from javac
when I compiled my example.

Interesting that Eclipse would give a warning for perfectly valid Java
code.

If it was not valid, then it would be an error not a warning.

The distinction between Eclipse and compiler is a bit fuzzy
since Eclipse uses its own compiler.

Arne
 

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

Forum statistics

Threads
473,981
Messages
2,570,187
Members
46,729
Latest member
ScarlettJe

Latest Threads

Top