面向对象基础练习中应使用多态数组+instanceof判断+向下转型调用子类特有方法,而非并发或动态组装;声明父类数组存放子类对象,统一调用共有方法,特有方法需先判型再转型,推荐用arraylist替代数组提升类型安全。

面向对象基础练习中,不应用“并发”或“动态组装”这类运行时调度思路来处理子类行为——这容易混淆设计期结构与运行期执行。所谓“利用数组动态组装子类特有行为”,实际指的是用多态数组 + 类型判断 + 向下转型的方式,在统一容器中管理不同子类对象,并按需调用其独有方法。核心是清晰、可控、可调试,而非真正意义上的“动态拼装”。
用父类/接口数组统一存放子类对象
声明数组时使用父类(如 Person)或接口(如 Drawable)类型,即可合法存入任意子类实例:
- Person[] people = new Person[5];
- people[0] = new Student("小明", 20, 95.5);
- people[1] = new Teacher("王老师", 35, 12000);
此时数组只认类型兼容性,编译通过,运行安全;所有元素都可直接调用父类共有的方法(如 say()),JVM 自动绑定到对应子类实现。
调用子类特有方法必须显式判断和转型
数组里存的是 Person 类型引用,无法直接访问 Student.study() 或 Teacher.teach()。必须先确认实际类型,再安全转换:
- 用 instanceof 判断:例如 if (p instanceof Student)
- 再强制转成具体子类:((Student) p).study();
- 避免空指针:确保对象非 null,且转型前已通过 instanceof 校验
这是基础练习中最标准、最推荐的做法,既体现多态本质,又保持逻辑透明。
用泛型集合替代数组提升类型安全性
虽然题目提“数组”,但实际开发中更常用 ArrayList
- 支持动态增删:list.add(new Student(...));
- 编译期类型检查更强(比原始数组更早暴露错误)
- 遍历时仍可配合 instanceof + 转型调用特有方法
若练习要求模拟“动态数组”,也可自己封装一个带扩容机制的容器(如 MyArrayList),内部仍用 Person[] 存储,对外提供 add/get 等灵活接口。
避免常见误区
初学阶段要特别注意以下几点:
- 不要试图用线程、定时器或回调“启动”子类行为——这不是 OOP 的扩展方式,而是混淆了并发模型与职责设计
- 不能绕过 instanceof 直接强转,否则运行时抛 ClassCastException
- 数组长度固定,越界访问会报 ArrayIndexOutOfBoundsException;用 length 控制循环范围
- 子类特有方法不应在父类中声明为抽象或默认实现——除非业务上所有子类都该有该行为,否则违背“里氏替换”原则











