Consider the following:
public class parent {
int x;
parent() {
x = 5;
}
}
public class child extends parent {
int y;
child() {
super();
y = 10;
}
public static void main(String[] args) {
parent p = new child();
System.out.println(p.y);//can't access variable y
}
}
Here a child class's constructor is being called on a parent class's object. I've come across this situation many times when doing Android programming. My question is why is this allowed? The child class's constructor might initialize additional members, but their blueprint might not be defined in the parent class like in the above case.
Why is it allowed for a parent class object to be instantiated using a child class's constructor?
That's not what's happening there. In this line:
parent p = new child();
...you're creating a child
object, not a parent
object. The variable you're using to refer to it, p
, has the type parent
, which means that you can only use parent
stuff via that reference, but the object is a child
object. The object does have a y
, you just can't access it via p
. You can see that by doing this:
parent p = new child();
System.out.println( ((child)p).y );
By telling the compiler we know that p
refers to child
even though it's of type parent
(via a "cast"), we can access the child
-specific parts of it. (This is not good practice when you have an alternative.)
This ability for there to be a difference (within constraints) between the reference you have to something and what it actually is is called "polymorphism" (taking multiple forms) and is central to object-oriented programming.
Consider:
class Animal {
}
class Dog extends Animal {
}
class Cat extends Animal {
}
All Dog
s are Animal
s, as are all Cat
s, but Dog
s are not Cat
s. Suppose you run a pet shop and want to store a list of the animals you have on hand:
List<Animal> animals;
The entries can be objects of type Animal
or any of its subtypes, such as Dog
and Cat
. This lets you have common aspects of animals on Animal
, and then only Dog
- or Cat
- specific aspects (properties or behaviors) on those types. You can run through your list of Animal
s acting on their animal-ness without worrying about whether they're Dog
s or Cat
s.
There is no instantiation of a parent class going on, except as part of instantiation of the child
in the constructor. You get one instance here, and that is an instance of a child
.
The assignment to parent p
is allowed because each child
object is also a parent
object.
Assigning a child
object to a variable with the type of its parent enables you to program to the interface of the class, limiting the use of the child
class to methods of its parent. This gives you flexibility to change implementation later:
Parent p = new OtherChild();
This way the code that uses p
does not need to know that it is accessing Child
or OtherChild
object.
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