xxxxxxxxxx
class Animal {
void eat() {
System.out.println("Animal is eating");
}
}
class Dog extends Animal {
void bark() {
System.out.println("Dog is barking");
}
}
public class Example {
public static void main(String[] args) {
Animal myAnimal = new Dog();
// Downcasting requires explicit casting and may throw a ClassCastException
if (myAnimal instanceof Dog) {
Dog myDog = (Dog) myAnimal;
myDog.eat(); // Accessing the base class method
myDog.bark(); // Accessing the derived class method
}
}
}
xxxxxxxxxx
// reference primitive, and its type
SportsCar sc = new SportsCar();
Car c = sc; // upcasting is implicit, this is OK!
sc.race(); // sc type is SportsCar, this is OK!
c.race(); // c type is Car, will NOT compile!
// Upcasting is implicit
Car myCar = new SportsCar(); // upcasting
Car myCar = sc; // upcasting is implicit
Car myCar = (Car) sc; // (Car) is not necessary
// Downcasting is explicit
// potential ClassCastingException
// b/c Java will not always be able to determine that you've specified the right types at compile time
// So if you make a mistake you may encounter a run time error - hence Generics.
SportsCar mySportsCar = (SportsCar) myCar; // potential ClassCastingException
((SportsCar) c).race(); // downcasting to allow specialized subclass methods