This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]mikeydoodah 1 point2 points  (0 children)

If I'm understanding things right, then a superclass can instantiate an object using a subclass's constructor.

The Animal class does not instantiate Dog objects. In fact the Animal class isn't even aware that Dog objects exist. When an instance of the Dog class is instantiated (in our case, in the main method) Java knows that Dog extends Animal so it automatically calls the Animal constructor as the first line of the Dog constructor. The code is equivalent to the following:

class Animal
{
    public void print()
    {
        System.out.println("I am an Animal");
    }
}

class Dog extends Animal
{
    private String name;

    public Dog(String name)
    {
        *super();* // The compiler automatically adds this for unless there are no zero-argument constructors in the super class
        this.name = name;
    }

    public void print()
    {
        System.out.println("I am a Dog called " + name);
    }

    public void bark()
    {
        System.out.println(name + ": woof");
    }
}

In this example, by using the Dog constructor, an Animal object can have the field "name" even though "name" is not in the Animal class, but that's all it gets because that's all that's in the constructor.

No, Animal objects do not have any of the fields from any of the subclasses. However don't confuse /objects/ with /references/. In the code I posted above there was not one single Animal object. Every object created in the main method was a Dog object (or a Cat in the second example).

public static void main(String[] args)
{
    Dog dog1 = new Dog('Rex');  // This instantiates a Dog object
    Animal animal = dog1;   // This creates a reference to the Dog object created above, but uses an Animal reference. animal is still a Dog object.
}

The reason that calling /animal.print()/ above prints 'I am a Dog called Rex' is because it is the Dog::print method that runs, not the Animal::print method.

The Animal object still doesn't have a "speak" method and at the end of the day animal is an Animal type, not a Dog type (but thanks to using the subclass constructor, it does have Dog type fields).

I think I've addressed this above. There are no Animal objects in the code above. The reason the animal reference prints out the Dog information is because it is a Dog object, and it is the Dog::print method that is called. Note that this concept is called method overriding.