编译器强制非抽象类必须实现所有继承的抽象方法,以保障多态调用的安全性与对象可实例化;抽象子类可延迟实现,将契约责任向下传递,最终由具体子类完整履行。

这是编译器层面的契约检查
抽象方法只声明不实现,意味着“该能力必须由具体子类提供”。Java、C#、Python(abc模块)等语言在编译或加载阶段就强制验证:只要一个类被声明为非抽象(即能被 new 出实例),它内部就不能存在任何未实现的抽象方法。这不是运行时逻辑判断,而是语法结构合法性检查——就像要求 if 后面必须跟括号和语句块一样基础。
不实现就等于留白,而具体类不能有留白
具体类要能创建对象、响应调用,所有公开行为都得有确定逻辑。如果 Dog 继承 Animal 并声明为普通类,但没写 eat() 的具体动作,那执行 dog.eat() 时系统根本不知道该做什么。语言设计不允许这种不确定性存在。所以编译器直接报错,拒绝生成字节码或类对象。
抽象子类是合法的“中转站”
允许子类也声明为 abstract,本质是把契约责任向下传递。比如 Mammal 继承 Animal 后不实现 eat(),只是增加 liveBirth() 方法,它仍属于设计中间层。此时 Mammal 的角色不是提供完整行为,而是定义更细粒度的抽象分类。只要最终出现一个非抽象子类(如 Human 或 Whale),且它实现了 Animal 和 Mammal 链上所有未实现的抽象方法,整个继承链就满足契约。
核心目的不是限制,而是保障多态可用性
强制实现让父类引用可以安全调用子类方法:Animal a = new Dog(); a.eat(); 这行代码能成立,前提是编译器100%确认 a.eat() 一定有具体实现。如果没有这个强制,多态调用就可能在运行时崩溃。所以这个规则实际是在源头堵住空指针式的设计漏洞,让接口一致性和对象可实例化同时得到保证。










