class Animal {
String speak() { return "..."; }
}
class Dog extends Animal {
String speak() { return "Woof"; }
}
class Cat extends Animal {
String speak() { return "Meow"; }
}
public class Main {
public static void main(String[] args) {
Animal a = new Dog(); // a parent reference holding a child object
Animal b = new Cat();
System.out.println(a.speak()); // Woof
System.out.println(b.speak()); // Meow
}
}
class Animal { }
class Dog extends Animal {
void fetch() { System.out.println("fetching"); }
}
class Cat extends Animal { }
public class Main {
public static void main(String[] args) {
Animal a = new Dog(); // upcast - implicit, safe
Dog d = (Dog) a; // downcast - explicit, valid because a is really a Dog
d.fetch();
Animal c = new Cat();
Dog wrong = (Dog) c; // compiles, but throws ClassCastException at runtime
wrong.fetch();
}
}
class Animal { }
class Dog extends Animal {
void fetch() { System.out.println("fetching"); }
}
class Cat extends Animal {
void scratch() { System.out.println("scratching"); }
}
public class Main {
public static void main(String[] args) {
Animal[] animals = { new Dog(), new Cat(), new Dog() };
for (Animal animal : animals) {
if (animal instanceof Dog dog) { // checks type AND binds dog
dog.fetch();
} else if (animal instanceof Cat cat) {
cat.scratch();
}
}
}
}
向上转型是把子类对象当作父类类型来对待(Animal a = new Dog();),它总是安全的,而且通常是隐式的。向下转型则反过来(Dog d = (Dog) a;),只有当对象确实是那个子类型时才安全,否则会抛出 ClassCastException。每次向下转型之前都先用 instanceof 检查。