多态入参需声明为父类或接口类型,实参传任意子类对象,编译器自动向上转型,运行时按实际类型动态调用重写方法;子类须正确重写父类/接口方法,java用@override,c++用virtual与override;集合可统一存放不同子类对象并遍历调用。

核心就一句话:方法参数声明为父类(或接口)类型,实参直接传任意子类对象——编译器自动完成向上转型,运行时按实际类型调用对应方法。
参数类型必须是父类或接口
这是多态入参的起点。形参不能写具体子类,否则每加一个子类就要重载一次方法。
- Java中写成 void process(Animal a) 或 void draw(Drawable d)
- C++中写成 void render(const Shape& s) 或 void handle(Base* obj)
- 避免 process(Dog d)、process(Cat c) 这类面向实现的写法
子类必须正确重写父类/接口方法
没有重写,就没有差异化行为;没有动态绑定,就谈不上多态。
- Java:子类用 @Override 重写非 private、非 static、非 final 的方法;接口实现类必须实现全部抽象方法
- C++:基类中对应函数需声明为 virtual,子类建议显式加 override
- 例如 Animal.eat() 被 Dog.eat() 和 Cat.eat() 分别覆盖,调用 process(new Dog()) 就执行狗的吃逻辑
调用时直接传子类实例,无需手动转型
只要继承关系成立、方法已重写,传参就是自然的。
- process(new Dog())、process(new Cat())、process(new Bird()) 全部合法
- C++ 中 render(circle)、render(rectangle) 同样成立,circle 是 Circle 类型对象,rectangle 是 Rectangle 类型对象
- 关键点:传的是对象本身(或其地址/引用),不是类型名;运行时根据实际对象类型决定调用哪个版本
集合批量处理让优势更明显
当要统一操作多个不同子类对象时,把它们放进父类/接口类型的集合里最直观。
- Java:List
animals = Arrays.asList(new Dog(), new Cat(), new Duck());
然后遍历:for (Animal a : animals) { a.eat(); } - C++:std::vector<:unique_ptr>> shapes;
添加:shapes.push_back(std::make_unique());
调用:for (const auto& s : shapes) s->draw(); - 新增子类(如 Fish)只需继承 Animal 并重写 eat(),原有处理逻辑一行不改











