You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

继承——面向对象编程(OOP)易混淆概念及相关问题

问题1:四种实例化场景的构造函数调用顺序

我逐个给你拆解每个场景的执行逻辑:

1. A a = new A();

调用顺序:1 → 2
解释:第一次创建A类的实例时,CLR会先触发A的静态构造函数(这个静态构造函数整个程序生命周期只会执行一次),然后再执行A的实例构造函数来初始化对象。

2. B b = new A();

调用顺序:1 → 2
解释:别被左边的B类型引用迷惑了!这里实际new的是A类对象,所以完全和场景1一样,B类的任何构造函数都不会被触发——毕竟我们根本没创建B的实例。

3. A c = new B();

调用顺序:1 → 3 → 2 → 4
解释:创建子类实例的规则是先处理静态构造,再处理实例构造:

  1. 首次创建B实例,先执行父类A的静态构造(1号);
  2. 接着执行子类B的静态构造(3号);
  3. 实例构造阶段,必须先调用父类A的实例构造(2号),再执行子类B的实例构造(4号)。
    不管左边的引用是A还是B,只要实例是B,这个顺序就不会变。

4. B d = new B();

调用顺序:1 → 3 → 2 → 4
解释:和场景3完全一致!引用类型不影响构造函数的执行顺序,只要实例化的是B,就严格遵循“父静态→子静态→父实例→子实例”的顺序。


问题2:方法重载/隐藏场景下的调用逻辑

这里分两种情况给你说明:

情况1:方法重载(B的Method()是重载版本)

重载的核心是方法签名不同(比如A是void Method(),B是void Method(int num))。题目里的调用都是无参数的Method(),所以所有调用都会命中A类的5号方法:

  • a.Method(); → 调用5号(A实例直接调用自己的方法)
  • b.Method(); → 调用5号(b的引用是B,但实际是A实例,执行A的无参方法)
  • c.Method(); → 调用5号(c是A引用,指向B实例,但B没有无参的重载方法,所以执行继承自A的5号)
  • d.Method(); → 调用5号(B实例的无参Method还是继承自A的,因为B的重载是带参的,不匹配调用)

情况2:方法隐藏(B用new关键字隐藏A的Method())

方法隐藏的核心是看引用类型,而不是实例类型:

  • a.Method(); → 调用5号(A引用指向A实例,直接用A的方法)
  • b.Method(); → 调用5号(B引用但实际是A实例,执行A的方法)
  • c.Method(); → 调用5号(A引用指向B实例,方法隐藏下父类引用只会调用父类的方法)
  • d.Method(); → 调用6号(B引用指向B实例,调用B自己隐藏的方法)

内容的提问来源于stack exchange,提问作者Samra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:56:47