多态的核心是继承+重写+向上转型,使新增子类无需修改老代码;仅非静态、非私有、非final的实例方法通过父类引用调用时才生效,static方法、成员变量等不参与动态绑定。

多态让新增子类不用改老代码
核心就一条:只要符合继承 + 重写 + 向上转型三个条件,新子类加进来,原有调用逻辑(比如 drawShape(Shape s))完全不用动。你不是在写“画矩形”“画圆形”的专用函数,而是在写“画一个图形”——这个接口天然接纳未来所有图形。
- 新增
Triangle类?只写类定义和draw()实现,然后传给已有的drawShape()就行 - 老代码里没有
if (s instanceof Triangle)这种判断,也就没有漏掉新类型的可能 - 如果硬编码每种类型,每次加新图形都要打开
DrawingProgram改方法、加分支、重新测试——这就是维护性崩塌的起点
父类引用屏蔽实现细节,接口更稳定
当你把参数类型定为 Shape 而不是 Rectangle 或 Circle,等于锁定了契约边界:只要它能 draw(),我就接受。子类内部怎么算面积、用什么坐标系、是否缓存渲染结果,统统不关心。
该系统采用多层模式开发,这个网站主要展示女装的经营,更易于网站的扩展和后期的维护,同时也根据常用的SQL注入手段做出相应的防御以提高网站的安全性,本网站实现了购物车,产品订单管理,产品展示,等等,后台实现了动态权限的管理,客户管理,订单管理以及商品管理等等,前台页面设计精致,后台便于操作等。实现了无限子类的添加,实现了动态权限的管理,支持一下一个人做的辛苦
- 比如
Circle.draw()后来改成用贝塞尔曲线逼近,只要输出效果一致,drawShape()完全无感 - 反之,如果方法签名是
drawRectangle(Rectangle r)和drawCircle(Circle c),那每个新图形都得配一个新方法,接口膨胀不可控 - 这种稳定性让单元测试也省心:你只测
drawShape(Shape)的行为,不用为每个子类单独写调用链
容易踩的坑:多态失效的典型场景
不是写了继承和重写就自动多态。JVM 只对实例方法做动态绑定,其他情况会“掉出多态轨道”。
-
static方法不参与多态:调用哪个static draw(),只看引用类型(Shape.draw()永远调父类的) - 成员变量访问不走多态:
shape.color读的是Shape类里定义的color,不是子类自己声明的同名字段 - 构造方法、私有方法、final 方法无法被重写,自然也没有多态行为
- 如果忘记重写父类方法(比如漏了
@Override),运行时调用的还是父类空实现或默认逻辑,问题很难一眼发现
abstract class Shape {
String color = "white"; // 注意:子类同名字段不会覆盖这里
abstract void draw();
static void info() { System.out.println("Shape static"); }
}
class Circle extends Shape {
String color = "red"; // 这个 color 不会影响 shape.color 的读取
void draw() { System.out.println("draw circle"); }
static void info() { System.out.println("Circle static"); } // 与父类静态方法无关
}
多态真正起效的地方很窄:仅限于「非静态、非私有、非 final 的实例方法」+「通过父类引用调用」。超出这个范围,看似像多态,实则只是普通继承或编译期绑定。









