In Java, inheritance and type casting operations follow specific rules that affect how objects can be assigned and converted between parenet and child classes. Consider the folloiwng class hierarchy:
class Animal {}
class Canine extends Animal {}
class Feline extends Animal {}
public class TypeCastingExample {
public static void main(String[] args) {
Animal a;
Canine c = new Canine();
Feline f = new Feline();
a = c; // Valid upcasting
// c = a; // Compile error
c = (Canine)a; // Valid downcasting
// c = f; // Compile error
// f = (Feline)a; // Runtime error
}
}
When examining different casting scenarios:
f = (Feline)a;throws a runtime ClassCastExceptionc = f;causes a compile-time type mismatch errorc = a;results in a compile-time type mismatch
Another example demonstrates polymorphism and field access:
class Parent {
int value = 1;
void display() { System.out.println(value); }
}
class Child extends Parent {
int value = 2;
void display() { System.out.println(value); }
}
public class InheritanceTest {
public static void main(String[] args) {
Parent p = new Parent();
p.display(); // Outputs 1
Child ch = new Child();
ch.display(); // Outputs 2
p = ch;
p.display(); // Outputs 2 (polymorphism)
p.value++;
p.display(); // Outputs 3
((Child)p).value++;
p.display(); // Outputs 4
}
}
Key Java concepts demonstrated:
- Polymorphism: Child objects can be treated as Parent objects
- Method overriding: Child methods override Parent methods
- Type casting: Parent references can be downcast to Child references
- Field access: Intsance variables are accessed based on reference type