【问题标题】:Do Java or C++ lack any OO features?Java 或 C++ 是否缺少任何 OO 特性?
【发布时间】:2010-03-16 19:33:08
【问题描述】:

我有兴趣以比目前更学术和抽象的方式理解面向对象编程,并想知道 Java 和 C++ 是否有任何面向对象的概念未能实现。

我意识到这两种语言都不是“纯粹的”面向对象,但我感兴趣的是它们缺少什么(如果有的话),而不是它们有什么额外的。

【问题讨论】:

  • 这需要你拼出“OO”的意思。
  • 我认为关键是 OP 并不知道确切的含义,而是想要一些扩展思维的东西。

标签: java c++ oop


【解决方案1】:

the words of Alan Kay,“面向对象”一词的发明者:

OOP 对我来说仅意味着消息传递,本地 保留、保护和隐藏 状态过程的和极端的 所有事物的后期绑定。有可能 在 Smalltalk 和 LISP 中完成。那里 可能是其他系统,其中 这是可能的,但我不知道 他们。

C++ 显然不符合“极端后期绑定”标准,而 Java 和 C++ 均不符合“消息传递”标准,因为它们具有严格的类/方法结构。据我了解,Kay 的概念认为具有特定名称和签名的方法是一种实现消息处理程序的便捷方式,但绝不是唯一的方式。

来自同一封电子邮件的其他有趣的陈述:

我不喜欢 Simula 我或 Simula 67 做了继承 [...] 所以我 决定排除继承作为 内置功能,直到我理解它 更好。

强加了“多态性”一词 很久以后(我认为是彼得·韦格纳) 而且它不是很有效,因为它确实来自函数的命名法,而且我想要的不仅仅是函数。

【讨论】:

  • Java 不也达不到前一个标准吗?
  • 这里的一个重要词是“所有”事物。例如,在 Smalltalk-71 中,语法是后期绑定的。在该语言的更高版本中,Smalltalk 实际上变得更加静态,这就是为什么 Alan Kay 想用一种全新的方法重新开始。事实上,Smalltalk-76 及以后的版本不再由他设计,它们并没有完全体现他对 OOP 的愿景,它们的继任者,如 Ruby,也没有。他目前正在研究的语言比 Smalltalk 或 Lisp 更具后期绑定和动态性,事实上,即使“后期绑定”的定义本身也是后期绑定的。
  • @Jörg W Mittag:听起来很酷。这种语言叫什么名字?
  • @FrustratedWithFormsDesigner:我认为它还没有名字。你可以在 Alan Kay 创立的研究所找到一些信息:VPRI.Org 另外,就像 Smalltalk 一样,它不仅仅是一种语言,它是一个完整的个人计算系统,由操作系统、驱动程序、图形用户界面、语言、编译器组成, Office Suite, Desktop Publishing, Networking, ... 令人惊奇的是:所有这些都在不到 20,000 行代码中完成。查看 VPRI 网站上的论文,或网络上的视频之一。
  • 人们不知道如何 OO Smalltalk。在 Smalltalk 中,new Foo() 的等价物是 Foo new。但它不是,真的 - 事实上,在 Smalltalk 中,这是一个发送给单例对象 Foo 的消息,它是一个 Class 对象。在 Smalltalk 中,if 是发送给对象的消息。 Java 和 C# 一切都是对象... Smalltalk 意味着它。
【解决方案2】:

在我的脑海中,我会说:

【讨论】:

    【解决方案3】:

    两者都区分基元和对象,因此都不是纯粹面向对象的。

    【讨论】:

    • @JRL:这绝不是“缺少功能”,问题特别指出发帖人知道 C++ 和 Java 不是纯 OO 语言。
    【解决方案4】:

    还有另一种思考面向对象编程的方式,它不同于 Java 和 C++ 中基于类的系统。 JavaScript 使用基于原型的编程。如果您想了解 OOP 样式的全部范围,可能值得一看:http://en.wikipedia.org/wiki/Prototype-based_programming

    【讨论】:

      【解决方案5】:

      Java:原始类型不是对象。

      【讨论】:

      • 这不是缺少的功能,而是一种语言设计特质。
      • 好吧,有些人(我)称 bug 缺少功能 :)
      • 你也不能用 C++ 写class MyInt: public int。无论如何,如果您希望它编译,则不是。
      • 如果您愿意,可以将其视为多根层次结构。 :)
      • 至少从 java 1.5 开始就有自动装箱功能,例如 int 原语与 Integer 对象的轻松交换。我同意,尽管它阻止了 java,从最严格的意义上说,完全面向对象的语言
      【解决方案6】:

      Java 没有多重继承,但有些人可能会说这更像是一种祝福,因为它要求用户考虑正确的体系结构。您可以使用接口和抽象类来解决这个问题。

      多重继承因其在某些语言(尤其是 C++)中引起的以下问题而受到批评:

      • 经常总结的语义歧义 作为diamond problem
      • 无法显式继承 同一堂课多次学习
      • 继承改变类的顺序 语义

      【讨论】:

      • @Chris Dennett:这根本不是真的。实现是一个细节,您需要知道您可以在 Java 中使用 any 疯狂的多重继承非常干净地简单地 翻译 any OOA/OOD(如你可以用甚至没有实现继承概念的语言来做)使用多接口继承。您可能对使用委托可以轻松实现的“代码重用”感到困惑。 200KLOC Java 代码库在这里我们使用 zero 时间实现继承......并且我们使用多重继承 everywhere
      • 好的,WizardOfOdds,Java 缺少接口委托。如果您希望某个类将接口 I 委托给对象 O,则必须手动创建 I 的所有方法,这些方法只是简单地调用 O 的相同方法。
      【解决方案7】:

      面向对象编程的一个最重要的特性是封装。隐藏实现细节对于编写可维护的代码显然至关重要。

      在 C++ 中,由于指针不受控制,一个写得不好的对象可能对另一个对象做任何事情。这意味着封装被破坏了,并且很难找到错误。

      Java 没有这个问题,但它缺乏基本的 const 特性。这不是严格意义上的面向对象的理论特性,但是能够声明一个方法是只读的,或者一个对象是只读的,是 C++ 中一个非常棒的可靠性增强器,而 Java 中没有。

      最后,java 的模板机制是对 C++ 的苍白模仿。无法对类进行参数化对 Java 来说是一个巨大的损失。

      因为 Java 不支持指向方法的指针,而且反射太慢,所以它强制使用许多小对象,而函数指针可以这样做。有些人可能认为这是一件好事。

      【讨论】:

        【解决方案8】:

        Java 和 C++ 都允许过程式编程。对某些人来说,这可以被认为是一个减号。

        【讨论】:

        • 事实上,我认为大多数 Java/C++ 代码程序性的,上面带有 OO 单板。
        【解决方案9】:

        大多数解释型语言都满足后期绑定要求。在 Perl 中,您可以从数据库表中提取代码,将其放入解释器中,然后实例化您刚刚引入程序的新类的对象。

        Python 是否完全符合 Kay 对 OOP 的定义?可以肯定的是,我在 Python 中做的工作还不够多。我怀疑不是,因为 Python 具有不是对象的“本机类型”。

        【讨论】:

        • 您指的是哪些“原生类型”?我在 Python 中没有遇到任何不是对象的东西。
        • 我的立场是正确的。来自 DiveIntoPython.org 的教程:“2.4.2。什么是对象?Python 中的一切都是对象,几乎所有东西都有属性和方法。”我可能在考虑常规变量,默认情况下它们没有任何属性。它们仍然是对象。耶 Python。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-28
        • 1970-01-01
        相关资源
        最近更新 更多