要让继承体系中真正发生多态,必须同时满足三点:一是存在明确的is-a继承关系(如dog extends animal);二是子类重写父类的可调用方法(java默认支持,c++需声明virtual);三是用父类类型引用或指针操作子类实例(如animal a = new dog()),三者缺一不可。

要让继承体系中真正发生多态,不是只要写了父子类就自动生效的。关键在于三点必须同时到位,缺一不可。
有明确的继承关系
这是整个机制的地基。父类和子类之间必须是is-a关系,比如Dog extends Animal、Student extends Person。接口实现也算广义继承,但纯组合或关联不行。
- 类之间用extends关键字声明继承
- 抽象类、普通类、接口均可作为父类型,但需保证子类确实继承/实现了它
- 单继承即可满足,不需要多重继承(Java不支持,C++虽支持但多态不依赖于此)
子类重写父类的可调用方法
重写不是可选动作,而是触发动态分派的核心开关。只继承不重写,调用的仍是父类逻辑,没有“不同形态”可言。
- 方法名、参数列表、返回类型必须与父类一致(Java中返回类型可协变)
- 访问权限不能比父类更严格(如父类public,子类不能写private)
- C++中该方法必须声明为virtual;Java中非static、非final、非构造方法默认支持重写
用父类类型引用或指针操作子类实例
这是多态发生的“现场”。只有通过统一的上层类型去调用,运行时才能根据实际对象类型决定执行哪份代码。
- Java写法:Animal a = new Dog(); a.sound();
- C++写法:Person* p = new Student(); p->BuyTicket();
- 不能直接用子类变量调用:Dog d; d.sound();——这属于静态绑定,不构成多态
- 数组、容器、函数参数中传递父类引用/指针,同样适用
不复杂但容易忽略:三个条件像三把钥匙,少一把门就打不开。写完继承和重写后,务必检查调用处是否用了父类视角;否则代码看似结构完整,实际只是普通继承调用。










