Java图形界面中多态通过接口Drawable或抽象类Shape实现绘制逻辑解耦:统一调用draw()或paint(),各子类自主实现具体绘制;结合repaint机制自动调度重绘,编译期受限于引用类型,运行时动态绑定实现。

Java 中多态在图形界面开发中统一处理不同组件绘制逻辑,核心是让“画什么”和“怎么画”解耦——用同一套调用方式,驱动不同类各自实现自己的绘制行为。
用接口定义统一的绘图契约
当按钮、图片、文本、自定义形状等组件没有继承关系,但都需要支持绘制(比如 draw()),接口是最自然的选择。它不关心对象是谁,只约定它必须能做什么。
- 声明一个 Drawable 接口:interface Drawable { void draw(Graphics g); }
- 让各类独立实现:Button、ImagePanel、ArrowShape 各自 implements Drawable,并在 draw() 方法里写各自的绘制代码(如 drawRect、drawImage、drawLine)
- 主绘图面板维护 List
,遍历时统一调用 d.draw(g),无需 if-else 判断类型,也不依赖具体类名
用继承体系组织同类图形的绘制差异
对于有明显层级关系的图形(如 Shape 体系),用抽象父类 + 子类重写更清晰。父类封装共性(如坐标、颜色字段),子类专注差异化逻辑。
- 定义抽象类 Shape,含 abstract void paint(Graphics2D g2d) 和通用属性(x, y, color)
- Circle、Rectangle、Polygon 继承 Shape,分别重写 paint():圆调用 g2d.fillOval(),矩形调用 g2d.fillRect()
- 绘图面板中用 Shape s = new Circle(100, 100, 50) 声明,调用 s.paint(g2d) 自动执行圆的绘制逻辑
结合 repaint 机制触发多态重绘
Swing 的重绘流程(repaint → paintComponent → 调用各组件绘制方法)天然适配多态。关键在于:状态变更后,只调用一次 repaint(),所有 Drawable 或 Shape 对象会在 paintComponent 中被统一调度绘制。
- 鼠标点击添加新图形时,把它加入 List
或 List - 不要在监听器里 new 主面板再调 repaint —— 这会操作错误实例;应把当前面板引用传入监听器,或用回调接口通知重绘
- 在 paintComponent(Graphics g) 中,先调 super.paintComponent(g) 清屏,再遍历列表调用每个元素的 draw(g) 或 paint((Graphics2D) g)
注意边界:引用类型决定能力,运行时才绑定实现
多态不是自动识别一切。编译期只允许调用接口或父类中声明的方法,子类独有方法无法通过多态引用访问。
- 声明为 Drawable d = new Button(),只能调 d.draw(g);不能调 d.setText("OK"),哪怕 Button 真有这个方法
- 若需临时使用子类特有功能(如获取按钮文字),应先用 instanceof 安全判断,再向下转型:if (d instanceof Button) { ((Button) d).setText("New"); }
- 避免在绘制逻辑中混用静态方法或 final 方法——它们不参与多态,无法被重写覆盖
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











