4

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.

343GuiltySpark
  • 123
  • 1
  • 2
  • 11
  • hint: whats the object `p` type and its base type? next `y` is declared in `child` class. – SatyaTNV Sep 24 '15 at 14:13
  • "Here a child class's constructor is being called on a parent class's object." - no, you define an object which is of type `child` but your rest of your code sees it as an object of `parent`. – Smutje Sep 24 '15 at 14:14
  • Hopefully you have a dictionary where you can look up "extend". In this context (`child extends parent`) it means that the child class has all the parent class has, plus some fields and methods of its own. – laune Sep 24 '15 at 14:18
  • Note: In Java, the *overwhelming* convention is to capitalize class names, e.g. `Parent`, not `parent`, and `Child`, not `child`. You don't have to follow convention in your own code, but it's useful to, and it's very useful to follow conventions when sharing code with others (for instance here, when asking questions). :-) – T.J. Crowder Sep 24 '15 at 14:20

4 Answers4

20

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 Dogs are Animals, as are all Cats, but Dogs are not Cats. 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 Animals acting on their animal-ness without worrying about whether they're Dogs or Cats.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
5

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.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
2

When you write parent p = new child();, it actually create object of child class. When it calls child class constructor, super class constructor get called first through super() call.

Rahman
  • 3,755
  • 3
  • 26
  • 43
1

Because a Child IS a Parent too. So it can adquire its type. But, the object will be a Child. So a Child object of type Parent.

Note: Class names are uppercase.

Javier Haro
  • 1,255
  • 9
  • 14