The 'new' keyword makes your machine allocate memory for a new object.
In this case, the new object you're initializing is an array, and the array has enough space to hold 4 animal objects in it. Since Cat extends animal, cats can be here as well, but any other animal can Dogs, Pigs, so long as they extend Animal.
Since this is an Array of type animal, even though cat objects are inside of it, you'll only be able to reference the method declarations of type animal.
Before we move to an example with arrays here is an example without arrays:
public static void main(String[] args) {
Animal myCat = new Cat();
// prints "meow". Works because it's from an animal method
myCat.speak();
// This doesn't work - unknown method - b/c it's not declared in animal class
myCat.lickSelf();
}
private static class Animal {
public void speak() {
System.out.println("barf");
}
}
private static class Cat extends Animal {
public void speak(){
System.out.println("meow");
}
public void lickSelf(){
System.out.println("slurp");
}
}
Now let's move to the array stuff:
Any object extending cat can fit here, but you can only access Animal properties.
public static void main(String[] args) {
Animal[] myCats = new Cat[4];
myCats[0] = new Cat(); // can only put cats in here
myCats[1] = new Cat(); // but can only reference Animal properties
myCats[2] = new Cat();
myCats[3] = new Animal(); // Throws exception, must be a cat.
myCats[1].speak(); // prints "meow"
// This doesn't work, even though a cat object is here.
//Can only reference as an Animal.
myCats[2].lickSelf();
}
If you want to use cat methods/properties you need to do this:
Cat[] myCats = new Cat[4]
If you want to use ONLY animal properties that may be overridden, but ONLY allow cats here, use this:
Animal[] myCats = new Cat[4]
If you want to use only animal properties, but allow any type of animals in:
Animal[] myCats = new Animal[4]