本文目录导读:

我来为您详细介绍Java中的转型(Type Casting)案例,包括向上转型、向下转型以及常见的实际应用场景。
基础知识准备
首先创建一个简单的类继承结构:
// 父类:动物
class Animal {
String name;
public Animal(String name) {
this.name = name;
}
public void eat() {
System.out.println(name + "正在吃东西");
}
public void sleep() {
System.out.println(name + "正在睡觉");
}
}
// 子类:狗
class Dog extends Animal {
public Dog(String name) {
super(name);
}
@Override
public void eat() {
System.out.println(name + "正在啃骨头");
}
public void bark() {
System.out.println(name + "汪汪叫");
}
public void wagTail() {
System.out.println(name + "摇尾巴");
}
}
// 子类:猫
class Cat extends Animal {
public Cat(String name) {
super(name);
}
@Override
public void eat() {
System.out.println(name + "正在吃鱼");
}
public void meow() {
System.out.println(name + "喵喵叫");
}
}
向上转型(Upcasting)案例
1 基本向上转型
public class UpcastingDemo {
public static void main(String[] args) {
// 隐式向上转型(自动发生)
Animal animal = new Dog("小黄");
animal.eat(); // 输出:小黄正在啃骨头(多态)
animal.sleep(); // 输出:小黄正在睡觉
// 显式向上转型
Animal animal2 = (Animal) new Cat("小花");
animal2.eat(); // 输出:小花正在吃鱼(多态)
// 注意:通过父类引用不能调用子类特有方法
// animal.bark(); // 编译错误!
}
}
2 方法参数中的向上转型
public class ParameterDemo {
// 接收任何Animal类型或其子类
public static void feedAnimal(Animal animal) {
System.out.println("开始喂食...");
animal.eat();
}
public static void main(String[] args) {
Dog dog = new Dog("旺财");
Cat cat = new Cat("咪咪");
// 自动向上转型
feedAnimal(dog); // 输出:旺财正在啃骨头
feedAnimal(cat); // 输出:咪咪正在吃鱼
// 还可以传入匿名对象
feedAnimal(new Dog("来福")); // 输出:来福正在啃骨头
}
}
3 集合中的向上转型
import java.util.ArrayList;
import java.util.List;
public class CollectionDemo {
public static void main(String[] args) {
// 使用父类类型存储多种子类对象
List<Animal> zoo = new ArrayList<>();
zoo.add(new Dog("哈士奇"));
zoo.add(new Cat("波斯猫"));
zoo.add(new Dog("金毛"));
// 统一处理所有动物
for (Animal animal : zoo) {
animal.eat(); // 多态调用
animal.sleep(); // 公共方法
// 不能直接调用子类特有方法
// animal.bark(); // 编译错误
}
}
}
向下转型(Downcasting)案例
1 基本向下转型
public class DowncastingDemo {
public static void main(String[] args) {
// 先向上转型
Animal animal = new Dog("小黑");
// 向下转型:需要显式转换
Dog dog = (Dog) animal;
dog.bark(); // 输出:小黑汪汪叫
dog.wagTail(); // 输出:小黑摇尾巴
dog.eat(); // 输出:小黑正在啃骨头
// 危险操作:错误的向下转型
Animal animal2 = new Cat("小白");
// Dog wrongDog = (Dog) animal2; // 运行时抛出ClassCastException
}
}
2 安全的向下转型(使用instanceof)
public class SafeDowncastingDemo {
public static void main(String[] args) {
List<Animal> animals = new ArrayList<>();
animals.add(new Dog("柯基"));
animals.add(new Cat("布偶"));
animals.add(new Dog("边牧"));
for (Animal animal : animals) {
// 使用instanceof检查类型
if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.bark();
dog.wagTail();
} else if (animal instanceof Cat) {
Cat cat = (Cat) animal;
cat.meow();
}
// 所有动物都可以吃的操作
animal.eat();
System.out.println("--------------");
}
}
}
3 实际业务场景:动物园管理系统
public class ZooManagementSystem {
// 动物表演
public static void performTrick(Animal animal) {
System.out.println("准备表演...");
if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.bark();
dog.wagTail();
System.out.println(dog.name + "表演了狗狗特技!");
} else if (animal instanceof Cat) {
Cat cat = (Cat) animal;
cat.meow();
System.out.println(cat.name + "表演了猫咪特技!");
} else {
System.out.println("未知动物,无法表演特技");
}
}
public static void main(String[] args) {
Animal dog = new Dog("Buddy");
Animal cat = new Cat("Kitty");
performTrick(dog); // 执行狗狗特技
performTrick(cat); // 执行猫咪特技
}
}
综合案例:图形绘制系统
// 抽象基类
abstract class Shape {
abstract void draw();
abstract double getArea();
}
class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
void draw() {
System.out.println("绘制圆形,半径:" + radius);
}
@Override
double getArea() {
return Math.PI * radius * radius;
}
public void rotate() {
System.out.println("旋转圆形");
}
}
class Rectangle extends Shape {
private double width, height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
void draw() {
System.out.println("绘制矩形,宽:" + width + ",高:" + height);
}
@Override
double getArea() {
return width * height;
}
public void fillColor(String color) {
System.out.println("填充颜色:" + color);
}
}
public class GraphicSystem {
// 绘制所有图形(向上转型的好处)
public static void drawAllShapes(Shape[] shapes) {
for (Shape shape : shapes) {
shape.draw(); // 多态调用
System.out.println("面积:" + shape.getArea());
}
}
// 特定图形的高级操作(向下转型)
public static void applySpecialEffect(Shape shape) {
if (shape instanceof Circle) {
Circle circle = (Circle) shape;
circle.rotate();
} else if (shape instanceof Rectangle) {
Rectangle rectangle = (Rectangle) shape;
rectangle.fillColor("蓝色");
}
}
public static void main(String[] args) {
// 向上转型存储
Shape[] shapes = {
new Circle(5.0),
new Rectangle(3.0, 4.0),
new Circle(3.0)
};
// 统一绘制
System.out.println("=== 绘制所有图形 ===");
drawAllShapes(shapes);
// 特殊处理
System.out.println("\n=== 应用特殊效果 ===");
for (Shape shape : shapes) {
applySpecialEffect(shape);
System.out.println("---");
}
}
}
转型注意事项总结
public class CastingBestPractices {
public static void main(String[] args) {
// 1. 向上转型总是安全的
Dog dog = new Dog("安全狗");
Animal animal = dog; // 自动向上转型,安全
// 2. 向下转型前必须使用instanceof检查
if (animal instanceof Dog) {
Dog safeDog = (Dog) animal; // 安全向下转型
}
// 3. 避免不必要的转型
// 不好的做法:
Object obj = new Dog("Tom");
if (obj instanceof Dog) {
Dog dog1 = (Dog) obj;
dog1.eat();
}
// 更好的做法:直接使用正确的类型
Dog dog2 = new Dog("Tom");
dog2.eat();
// 4. 现代Java的Pattern Matching(Java 16+)
if (animal instanceof Dog d) {
d.bark(); // 自动转换,无需显式转型
d.wagTail();
}
// 5. 转型与多态的配合使用
Animal[] animals = {new Dog("多态1"), new Cat("多态2")};
for (Animal a : animals) {
a.eat(); // 多态调用,无需转型
}
}
}
常见错误及解决方案
public class CastingErrors {
public static void main(String[] args) {
// 错误1:错误的类型转换
// Cat cat = new Dog("错误"); // 编译错误,不能直接转换
// 错误2:运行时ClassCastException
Animal animal = new Dog("小白");
// Cat cat = (Cat) animal; // 运行时异常!
// 解决方案:使用instanceof检查
if (animal instanceof Cat) {
Cat cat = (Cat) animal;
}
// 错误3:null转型
Dog nullDog = null;
// Animal nullAnimal = (Animal) nullDog; // 编译通过,但后续操作会出问题
// nullAnimal.eat(); // NullPointerException
}
}
这些案例展示了Java转型的核心概念和实际应用,向上转型用于实现多态和代码复用,而向下转型用于访问子类特有功能,但需要谨慎使用并配合instanceof进行类型检查,向上转型安全优先,向下转型安全第一。