为什么静态成员会降低语言的面向对象性?

2024-05-02

我现在正在学习 Scala,我在 Odersky 的《Scala 编程》第二版中看到了这样的说法:

Scala 比 Java 更面向对象的一种方式是 Scala 中的类不能有静态成员。

我在 Java 或 Scala 方面都没有足够的经验,无法理解这种比较。为什么拥有静态成员会让语言变得不那么面向对象?


奥德斯基的说法是正确且有意义的,但有些人不明白他的意思。

假设在 Java 中你有一个带有方法 f 的 Foo 类:

class Foo {
  int f() { /* does something great */ }
}

您可以编写一个接受 Foo 并在其上调用 f 的方法:

void g(Foo foo) { foo.f(); }

也许有一个类 SubFoo 扩展了 Foo; g 也适用于此。可以有一整套类,通过继承或接口相关,它们共享可以与 g 一起使用的事实。

现在让我们创建 f 方法static:

class Foo {
  static int f() { /* does something great */ }
}

我们可以像这样将这个新的 Foo 与 g 一起使用吗?

g(Foo);  // No, this is nonsense.

该死。好的,让我们更改 g 的签名,以便我们可以将 Foo 传递给它并让它调用 f。

哎呀——我们不能。我们无法传递对 Foo 的引用,因为Foo 不是某个类的实例。一些在这里评论的人对有一个与 Foo 对应的 Class 对象这一事实感到困惑,但正如 Sotirios 试图解释的那样,该 Class 对象没有 f 方法,并且 Foo 不是该类的实例。 Foo 不是任何事物的实例;它根本不是一个物体。 Foo 的 Class 对象是 Class 类的一个实例,它具有有关 Foo 的信息(将其视为 Foo 的内部维基百科页面),并且是完全不相关进行讨论。维基百科上的“老虎”页面并不是老虎。

在 Java 中,像 3 和 'x' 这样的“基元”不是对象。他们areScala 中的对象。为了提高性能,您的程序将在执行过程中尽可能使用 JVM 原语 3 和“x”,但在您编写代码的级别上,它们实际上是对象。事实是他们是not对于任何试图编写处理所有数据类型的代码的人来说,Java 中的对象都会带来相当不幸的后果——您必须有特殊的逻辑和附加方法来覆盖原语。如果您曾经见过或编写过此类代码,您就会知道它很糟糕。奥德斯基的说法并不是“纯粹主义”;而是“纯粹主义”。离得很远。

在 Scala 中,没有任何运行时数据不是对象,也没有任何可以调用非对象方法的东西。在 Java 中,这些陈述都不是真的; Java 是一种部分面向对象的语言。在Java中,有些东西不是对象,有些方法不是对象上的。

Scala 新手经常会想到object Foo作为 Java 静态的一些奇怪的替代品,但这是你需要快速克服的东西。相反,将 Java 的静态方法视为非 OO 疣,而将 Scala 的静态方法视为非 OO 疣。object Foo { ... }沿着这些思路:

class SomeHiddenClass { ... }
val Foo = new SomeHiddenClass  // the only instance of it

这里 Foo 是一个value, not a type,它确实是一个对象。它可以传递给一个方法。它可以扩展一些其他类。例如:

abstract class AbFoo { def f:Int }
object Foo extends AbFoo { def f = 2 }

现在,你终于可以说

g(Foo)

确实,类的“伴生对象”是放置该类的非实例方法和数据的好地方。但该伴生对象是一个对象,因此通常的规则和功能适用。

事实上,在 Java 中,您将此类方法放在非对象上(限制它们的使用方式),这是一种负担,而不是一种功能。肯定是not OO.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么静态成员会降低语言的面向对象性? 的相关文章

随机推荐

  • 无法删除 windows 对象的事件侦听器

    我在尝试删除事件监听器时遇到了很多麻烦 我创建了一个非常依赖 JavaScript 的网站 当您在网站上导航时 它基本上是动态加载元素 而无需使用模板文字刷新页面 有时我必须加载内容并添加无限滚动 但也能够再次删除该事件 这是我用来处理滚动
  • MATLAB:生成给定三种颜色的颜色图

    我正在尝试在 MATLAB 中生成给定三种颜色 最高值 零值和最低值 的颜色图 我的思维过程是从最高端到中间循环 并将每个步骤存储到一个 3xN 第一列是 R 第二列是 G 第三列是 B 矩阵 所以我正在使用 fade from high
  • 谷歌地图动画符号(到达路径的目的地点后停止图标)

    我正在做一个学校项目 我正在使用 Google Map API API 很棒 但我需要一些代码方面的帮助 到达目的地后 我希望图标保留在那里 而不应该再次重复整个路径 function initMap var map new google
  • Java Paint 组件转换为位图

    我需要在位图中绘制组件及其所有子组件的内容 如果我想绘制整个组件 以下代码可以完美运行 public void printComponent Component c String format String filename throws
  • 使用 py2exe 在 .exe 中嵌入图标,在 Vista 中可见?

    我一直在尝试使用 py2exe 将图标 ico 嵌入到我的 编译 exe 中 Py2Exe 确实有一种嵌入图标的方法 windows script MyScript py icon resources 1 MyIcon ico 这就是我正在
  • 如何使用 jquery load 方法将文件的内容加载到变量中?

    如何使用 jQuery 将文件内容加载到变量而不是 DOM 中 load method 例如 logList load logFile function response 而不是将文件加载到 logListDOM 元素 我希望将其加载到变量
  • Gevent被flask阻塞甚至使用猴子补丁

    我正在使用flask gevent来构建我的服务器 但是名为 getall 的gevent被flask阻止 因此 getall 函数无法在这段代码中打印消息 猴子补丁正在使用中 import time import WSGICopyBody
  • 安装MySQLdb(对于python)作为非压缩的egg

    安装说明是 python setup py build sudo python setup py install or su first 这给了我一个 egg 文件 如何告诉安装程序将文件转储为普通的未压缩库 Thanks 好吧 我不想回答
  • WiX Burn:从注册表读取 LaunchTarget

    我是 WiX 的新手 我试图让我的 Bootstrapper 在完成后启动我安装的应用程序 为了实现这一点 我正在使用
  • 调试 SSR node.js 服务器端 VSCode

    我在尝试调试 SSR React 应用程序 服务器端 时花费了太多时间 我们正在从头开始构建一个应用程序 这是一个非常大的项目 因此调试代码非常重要 服务器的 webpack 配置如下 const path require path con
  • 检测活动 RDP 会话

    我需要在我的应用程序中实现死人开关 如果应用程序从 RDP 运行 我需要在它失去与远程客户端的连接时采取行动 我知道当我在 RDP 中运行时使用 GetSystemMetrics SystemMetric SM REMOTESESSION
  • 卸载屏幕外的 UIImageView 图像

    我正在 Ipad 上编写一个应用程序 在我的应用程序的某个时刻 我使用presentModalViewController 呈现一个ViewController 我的 ViewController 是一个 UISScrollView 它采用
  • 播放框架 Ebean BigDecimal 分数

    我正在使用带有 Ebean 和 H2 数据库的 Play 框架 问题是 BigDecimalDB 脚本的结果为 sum decimal 38 但我想要的是 sum decimal 38 2 我已经尝试像这样定义模型中的值 Digits in
  • c++ 如何释放和删除指向对象的指针的二维数组

    在SO问题 如何在C 中分配指针的二维数组 1 中 接受的答案还说明了如何取消分配和删除所述数组的正确过程 即 小心删除包含的指针 行数组和列数组全部分开且顺序正确 因此 我已经在元胞自动机模拟程序中成功地使用了这个二维阵列 但是 我无法使
  • 今天 iCloud + Core Data(2015 年 7 月 10 日)

    几年前 Apple 发布了 Core Data 应用程序的 iCloud 同步 然后我发布了一个适用于 iPad iPhone MAC 的应用程序 其共享模型使用新的 Apple 机制 事情并没有按预期进行 同步机制有时不起作用 例如 就我
  • IE10及以下浏览器检测

    我只想只针对 IE10 及以下版本的 IE 浏览器 请帮助我 我试过下面的代码 var userAgent navigator userAgent var regexIe8 new RegExp Trident 4 0 Trident 5
  • 动态 CRM 插件注册工具返回不安全或安全错误的错误

    我在尝试使用 SDK 中的插件注册工具注册插件时遇到错误 这个问题不知从何而来 因为在今天之前我总是能够轻松地使用该工具进行插件注册 错误信息是这样的 未处理的异常 System ServiceModel Security MessageS
  • 如果对象被破坏,打字稿类型会失败

    我有一个函数返回带有两个属性 res mes 的对象 其中一个为空 const fetchJSON
  • 如何将 CLI 应用程序作为 Windows 服务运行?

    假设我有一个第三方应用程序 它执行后台工作 但将所有错误和消息打印到控制台 这意味着 目前我们必须保持用户登录到服务器 并在每次重新启动时重新启动应用程序 双击 不太酷 我有点确定 有一种简单的方法可以做到这一点 通用服务包装器 可以使用日
  • 为什么静态成员会降低语言的面向对象性?

    我现在正在学习 Scala 我在 Odersky 的 Scala 编程 第二版中看到了这样的说法 Scala 比 Java 更面向对象的一种方式是 Scala 中的类不能有静态成员 我在 Java 或 Scala 方面都没有足够的经验 无法