Why does the following Java code produces:
10
superclass
The code in question is:
class SuperClass {
int a;
public SuperClass() {
this.a = 10;
}
private void another_print() {
System.out.println("superclass");
}
public void print() {
System.out.println(this.a);
this.another_print();
}
}
class SubClass extends SuperClass {
int a;
public SubClass() {
this.a = 20;
}
private void another_print() {
System.out.println("subclass");
}
public void print() {
super.print();
}
}
public class Main {
public static void main (String[] args) {
SubClass c = new SubClass();
c.print();
}
}
There is no instance of SuperClass
ever created, isn't there?
Not only that Java starts looking for the method to invoke from the SuperClass
, it even somehow knows that a = 10
!
Let's consider a similar Python code:
class SuperClass:
def __init__(self):
self.a = 10
def another_prn(self):
print('superclass')
def prn(self):
print(self.a)
self.another_prn()
class SubClass(SuperClass):
def __init__(self):
self.a = 20
def another_prn(self):
print('subclass')
def prn(self):
super().prn()
c = SubClass()
c.prn()
It works as I expect:
20
subclass
The only explanation that my colleagues (Python disliking Java folks) came up with is: "Python is not a true OOP language". Not very convincing at all.
Update: private void another_print()
is my blunder, I should have used protected
.
It is the order of constructor calling in Java.
In the SubClass
, when you instantiate c
, the constructor implicitly calls the default constructor of the SuperClass
(public SuperClass()
) (it must do so). Then a
is set to be 10 in the SuperClass
.
Now that we're done with the SuperClass
constructor, we get back to the constructor of SubClass
, which assigns a = 20
. But fields are not subject to overriding in java, so a
in SuperClass
is still 10.
After that it's pretty obvious, we call c.print()
which calls the print
of SubClass
, which calls the print
of SuperClass
(by super.print()
), which prints a
which is as you remember 10. Then another_print
(which is not overridden since it is private
) just prints superclass
and we're done.
In the sub-class's print you just call super-class's print method. So it prints the a from the super class of course.
You have two separate a fields here. Fields are not subject to overriding, only methods are. The super-class has an a field and you have another a field in the sub-class.
If another language produces another result, that's not a big surprise. Also, I am not sure your Python code is logically equivalent/analogous to your Java code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With