Reputation: 85
class Parent {
String st = "external";
void print() {
System.out.println(st);
System.out.println(this.st);
}
}
class Child extends Parent {
String st = "inner";
}
public static void main(String[] args) {
new Child().print(); // shows "external"
}
Why does print()
called on subclass not show the string "inner"?
Upvotes: 1
Views: 97
Reputation: 1759
The other answers cover why the behavior you notice is expected, so I won't touch on that. In terms of a solution to your problem, there are a few worth mention (neglecting things like reflection and subclass casting; technically solutions, but poor ones).
As Will mentioned, can simply set the parameter in Child:
class Child extends Parent{
public Child() {
st = "inner";
}
}
Can also override the print()
method (because, as mentioned, only methods can be overridden). Child
would become something along the lines of:
class Child extends Parent{
...
@Override
void print() {
// Child-specific implementation here.
}
}
This will result in Child
objects using their print method in place of Parent
's method.
Another option is to use Strategy pattern. Consider the following:
public interface Strategy {
String getString();
}
public class ParentStrategy implements Strategy {
@Override
public String getString() {
return "external";
}
}
public class ChildStrategy implements Strategy {
@Override
public String getString() {
return "inner";
}
}
From here, all you need to do is change your Parent object so that it defaults to ParentStrategy, provide accessors to change the Strategy, change its print method to use the getString() method of its Strategy object, and change the Strategy in Child to use ChildStrategy:
class Parent{
Strategy strat = new ParentStrategy();
void setStrategy(Strategy s) {
strat = s;
}
void print() {
System.out.println(strat.getString());
}
}
class Child extends Parent{
public Child() {
super();
setStrategy(new ChildStrategy());
}
}
In real world applications, this pattern is a fundamental tool to making flexible applications.
Upvotes: 0
Reputation: 29844
As the others mentioned the field st
of the Parent
class is hidden. Just an addition if you want it to print "inner".
Change Child
class to this:
class Child extends Parent {
public Child() {
st = "inner";
}
}
This way the value of st
from the Parent
class is overriden!
Upvotes: 1
Reputation: 206796
why print() called on subclass doesn't show string - "inner" ?
Because member variables cannot be overridden. The member variable st
in class Child
does not override the member variable st
in class Parent
. The two member variables are two separate variables, which happen to have the same name.
The methods in class Parent
see the member variable st
that is defined in class Parent
, and not the one in class Child
, even if the object is really an instance of class Child
.
Only methods can be overridden.
More information in Oracle's Java Tutorials: Hiding Fields (thanks @JonK).
Upvotes: 2
Reputation: 48258
why print() called on subclass doesn't show string - "inner" ?
why should it? you are calling the method print()
that is only override in the parent class up there in the parent class st is only holding the value "external"
Upvotes: 0