惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
SegmentFault 最新的问题
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
B
Blog RSS Feed
Y
Y Combinator Blog
T
Tailwind CSS Blog
博客园 - 三生石上(FineUI控件)
J
Java Code Geeks
Stack Overflow Blog
Stack Overflow Blog
aimingoo的专栏
aimingoo的专栏
Jina AI
Jina AI
The GitHub Blog
The GitHub Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
A
About on SuperTechFans
H
Hackread – Cybersecurity News, Data Breaches, AI and More
D
Docker
酷 壳 – CoolShell
酷 壳 – CoolShell
C
Check Point Blog
M
MIT News - Artificial intelligence
Last Week in AI
Last Week in AI
V
V2EX
腾讯CDC
F
Fortinet All Blogs
博客园 - 叶小钗
T
The Blog of Author Tim Ferriss

V2EX

我用 AI 写代码,但终端管理反而成了累赘——于是我做了 codux [调研] 各位在公司都用什么 ide 和 agent 写代码? 老运维 share 一个运维平台 新电脑 brew install node 之后,一个小设置可以提升对供应链投毒的防御 GLM-Coding 调用持续报错: z.ai 的 Lite 套餐几乎无法使用,官方 Pro/Max 是否稳定? 上海漕河泾内推,本组有 2 个 hc,一个后端,一个前端,预算都是 20k 左右,不打卡,氛围好 如果 V2EX 上有一组不永久保存聊天记录(比如只保存 7 天或者 24 小时)的聊天室,那么会开启哪些有用或者有趣的可能? gemini cli 貌似挂了,一直返回 403 第一次在自媒体上赚到钱 收集了最近在使用的低价 GPT, Gemini,邮箱等 AI 会员的小店合集 讨论个大实话:现在企业还在说 AI 编程提效 20%, 30%的,真的太落后,没用懂 AI。因为包括很多前沿公司,已经狂奔到提效 200%-500%的情况 [招聘][远程][币安] 前端/后端/QA/iOS/Android 至少 3 年以上经验 目前有大量 HC 欢迎投递 Chatgpt Pro 用量用不完的可以开这些设置 面试的时候好像遇到钓鱼了,给各位避个坑 cursor 年续费 22 号到期, 自动续费是否还是老的计次套餐呢 被两件破事毁掉的一下午,琐碎的内耗消磨人的精力 使用 Planet 存储 Codex 的会话或者重要信息 如果业务部门领导不要你开发功能,而是要求你教会它用 claude code 开发功能,你会怎么做? 分享一个 MacOS 接绿联 CM818 USB 转 DP 转接器使用感受 我的 HR 朋友 10 年老 Java ,非全大专,大家帮忙看看简历 开源了一个 AI 口语练习工具,音素级发音评分,完全免费可自部署 V2EX 上有哪些你觉得很有趣、印象深刻的妹纸? 字节为啥不出个国内版 Vercel? 有在大马的朋友吗? 问个运营商问题 你们在有领导的公司大群发过的最大胆的消息是什么 公司裁员,目前没有工作。想试试摆摊,做一个移动鲜啤打酒车 我的硬盘 Memblaze Pblaze 5 Linux 下不识别,给 Linux 内核提交了补丁, AI 说有望被合并 只有我一个人觉得 codex 不好用? 做了个 AI + 真人专家监督的广告投放平台 Auxora, 7 个品牌跑出 6x ROAS
下面这段 Java 多态的代码,如何才能改为 Go、 Python 、JS、...
jarryli · 2026-03-18 · via V2EX

面向对象包括封装、继承、组合、多态,其中最不好理解,也最强悍的就是多态。可以说掌握了多态就掌握了面向对象以及设计模式的精髓。

但是 java 里面的多态实现太过于严苛,以致于其他语言都无法完全模拟。请看下面的代码,用其他语言实现的时候总难以达到类似效果。

/*
多态:即同一个行为具有多个不同表现形式或形态的能力。
表现形式为,子类重写父类方法,实现类实现接口方法,子类重写抽象类方法等。
多态三个必要条件:继承、重写、父类引用指向子类对象。多态有效消除类型之间的耦合,并提供灵活的可扩展方案。
本例子简单清晰明了的 Java 多态,能看懂这个例子就懂了什么是多态。
*/

// 父类 A
class A {
    public String show(D object) {
        return ("A and D");
    }

    public String show(A object) {
        return ("A and A");
    }

    // 默认注释掉。可开关注释测试下
    // public String show(B object) {
    // return ("A and B");
    // }
}

// 子类 B
class B extends A {
    public String show(B object) {
        return ("B and B");
    }

    public String show(A object) {
        return ("B and A");
    }
}

// 孙子类 C
class C extends B {
}

// 孙子类 D
class D extends B {
}

// 测试验证
public class PolymorphismSimple {
    public static void main(String[] args) {
        // 父类声明自己
        A a = new A();
        // 父类声明子类
        A ab = new B();
        // 子类声明自己
        B b = new B();
        C c = new C();
        D d = new D();

        // 1) A and A 。b 的类型是 B ,也是 B 的实例,A 里没有 show(B)方法,但有 show(A)方法。B 的父类是 A ,因此定位到 A.show(A)。
        System.out.println("1) " + a.show(b));

        // 2) A and A 。c 的类型是 C ,也是 C 的实例,C 继承 B ,B 继承 A 。A 里没有 show(C)方法,也没有 show(B)方法,最后指向 A.show(A)。
        System.out.println("2) " + a.show(c));

        // 3) A and D, d 的类型是 D ,也是 D 的实例,D 继承 B ,B 继承 A 。A 里有 show(D)方法,直接定位到 A.show(D)。
        System.out.println("3) " + a.show(d));

        // 4) B and A, ab 是 B 的实例,但用 A 声明,即向上转型得到的类型是 A ,运行时才能确定具体该调用哪个方法。
        // ab 是 B 的实例对象,但引用类型是 A 。类型是在编译时确定,因此从类型开始定位方法。
        // A 类中没有 show(B)方法,但有 show(A)方法,因为 A 是 B 的父类,ab 也是 A 的实例,于是定位到 A.show(A)方法。
        // 由于 B 是 A 的子类,且 B 重写了 A 的 show(A),A 的方法被覆盖了,于是定位到 B.show(A),这就是动态绑定。
        // 虽然 B 中有 show(B)方法,但是因为 ab 的类型是 A ,编译时根据类型定位到 A 的方法,而不是 B 。

        // 以下几种可开关打开/注释代码测试下。
        // -
        // 若 A 里有 show(A)和 show(B),B 里有 show(B)有 show(A),则编译时关联到 A.show(B),因 B 覆盖了 A.show(B),动态绑定到 B.show(B)。
        // -
        // 若 A 里有 show(A)和 show(B),B 里无 show(B)有 show(A),则编译时关联到 A.show(B),因 B 无覆盖,则直接调用 A.show(B)。
        // -
        // 若 A 里有 show(A)无 show(B),B 里无 show(B)有 show(A),则编译时关联到 A.show(A),因 B 覆盖了 A.show(A),动态绑定到 B.show(A)。
        // -
        // 若 A 里有 show(A)无 show(B),B 里无 show(A)有 show(B),则编译时关联到 A.show(A),因 B 无覆盖,则直接调用 A.show(A)。
        // 查找顺序为:编译时根据引用类型确定所属类 -> 根据重载参数类型定位(类型按子->父->祖逐级往上查找)到类的具体方法(包括继承的方法) ->
        // 运行时实例对象覆盖(覆盖只有子->父一层)了引用类型的同名方法 -> 定位到实例对象的方法。
        System.out.println("4) " + ab.show(b));

        // 5) B and A 。ab 是 B 的实例,类型是 A 。从 A 类没找到 show(C)方法,也没找到 A.show(B)方法,找到 A.show(A)方法。A.show(A)被 B.show(A)覆盖,因此调用 B.show(A)。
        System.out.println("5) " + ab.show(c));

        // 6) A and D 。A 里面有 show(D)的方法,直接定位到。
        System.out.println("6) " + ab.show(d));

        // 7) B and B 。B 里面有 show(B)的方法,直接定位到。
        System.out.println("7) " + b.show(b));

        // 8) B and B 。B 没有 show(c)方法,但有 show(B)方法。C 继承自 B ,父类型是 B ,因此调用 B.show(B)。
        System.out.println("8) " + b.show(c));

        // 9) A and D 。B 中没有 show(D)方法,B 继承 A ,A 里有 show(D), 故调用 A.show(D)方法。
        System.out.println("9) " + b.show(d));

        // 10) B and A 。父类声明子类,存在向上转型。A 里有 show(A),被 B.show(A)覆盖了,因此定位到 B.show(A)。
        System.out.println("10) " + ab.show(a));

    }
}

/**
 * 测试结果
 * 1) A and A
 * 2) A and A
 * 3) A and D
 * 4) B and A
 * 5) B and A
 * 6) A and D
 * 7) B and B
 * 8) B and B
 * 9) A and D
 * 10) B and A
 */

其他语言模拟实现: https://github.com/microwind/design-patterns/tree/main/programming-paradigm/object-oriented-programming/polymorphism