【问题标题】:Why don't oop languages have a 'read only' access modifier?为什么 oop 语言没有“只读”访问修饰符?
【发布时间】:2010-07-17 11:04:08
【问题描述】:

每次我编写琐碎的 getter(获取只返回成员值的函数)时,我想知道为什么 oop 语言不简单地有一个“只读”访问修饰符来允许读取对象成员的值但不允许您像 C++ 中的 const 一样设置它们。

private、protected、public 访问修饰符为您提供完全(读/写)访问权限或无访问权限。

编写一个 getter 并每次调用它都很慢,因为函数调用比仅仅访问一个成员要慢。一个好的优化器可以优化这些 getter 调用,但这是“魔术”。而且我认为学习某个编译器的优化器如何工作并编写代码来利用它并不是一个好主意。

那么在实践中,为什么我们需要编写访问器、只读接口,而只是一个新的访问修饰符就可以解决问题呢?

ps1:请不要说“它会破坏封装”之类的东西。公开的foo.getX() 和公开但只读的foo.x 会做同样的事情。

编辑:我没有写清楚我的帖子。对不起。我的意思是你可以在外面读取成员的值,但你不能设置它。您只能在类范围内设置其值。

【问题讨论】:

  • 您的 ps1 假设 Property Getter 始终是字段变量的简单封装,但情况并非总是如此。例如,属性getter可能是一个包含多个字段的计算、字段的串联等。属性getter封装了逻辑,因此可以轻松更改内部实现。
  • 响应您的编辑,Marcelo Cantos 的回答或我的回答将完全满足您的需要。

标签: oop programming-languages


【解决方案1】:

您错误地将您所知道的一种或几种 OOP 语言概括为一般的 OOP 语言。一些实现只读属性的语言示例:

  • C#(感谢 Darin 和 tonio)
  • Delphi(= Object Pascal)
  • 红宝石
  • 斯卡拉
  • Objective-C(感谢拉诺)
  • ...更多?

就我个人而言,我很生气 Java 还没有这个(还没有?)。看到其他语言的特性后,用 Java 编写样板文件似乎很烦人。

【讨论】:

  • @BoltClock:好点,但最终字段与只读属性的语义不同。后者通常会允许类有一个私有后门来更改底层值,同时保持封装对外部的安全,这可能是一个很好的好处。 final 是...最终。
  • 如果 Java 的 final 不算数,那么 Scala 的 val 也不应该算数。
  • 啊,但是 Scala 比 Java 提供了更多的灵活性。虽然 valvar 以最少的编码处理 90% 的默认情况,但您可以通过执行 def foo = privateFoo 定义一个只读的私有可变属性 foo。它只是挥手和语法,但比 Java 简洁得多。
  • Swift 具有与 ObjC 基本相同的机制。
【解决方案2】:

好吧some OOP languages do have这样的修饰符。

【讨论】:

    【解决方案3】:

    在 C# 中,您可以在集合上定义具有不同访问限定符的自动属性并获取:

    public int Foo { get; private set; }
    

    这样,类实现可以根据其核心内容修改属性,而客户端代码只能读取它。

    【讨论】:

      【解决方案4】:

      C# 有readonly,Java 和其他一些有final。您可以使用它们将您的成员变量设为只读。

      在 C# 中,您可以为您的属性指定一个 getter,这样它就只能被读取,而不能被更改。

      private int _foo;
      
      public int Foo
      {
          get { return _foo; }
      }
      

      【讨论】:

      • public int Foo {get; private set;} 是实现此目的的另一种方法。没有附加声明
      【解决方案5】:

      实际上,不,它们不一样。 Public foo.getX() 仍然允许内部类代码写入变量。只读的foo.x 对于内部类代码也是只读的。

      有些语言确实有这样的修饰符。

      【讨论】:

      【解决方案6】:

      C# 属性允许轻松定义只读属性。看到这个article

      【讨论】:

        【解决方案7】:

        【讨论】:

          【解决方案8】:

          在德尔福中:

          strict private
            FAnswer: integer;
          public
            property Answer: integer read FAnswer;
          

          声明一个访问私有字段FAnswer的只读属性Answer。

          【讨论】:

            【解决方案9】:

            问题主要归结为:为什么不是每种语言都像 C++ 一样具有 const 属性?

            这就是它不在 C# 中的原因:

            安德斯·海尔斯伯格:是的。关于 const,这很有趣,因为我们 也一直听到这种抱怨: “你为什么没有 const?”隐式 问题是,“你为什么不 有 const 由 运行时?”这就是人们所说的 在问,虽然他们不来 出来这样说。

            const 在 C++ 中起作用的原因是 因为你可以把它扔掉。如果你 不能把它扔掉,然后你的世界 会很烂。如果你声明一个方法 这需要一个 const Bla,你可以通过 它是一个非常量 Bla。但如果是 其他方式你不能。如果你 声明一个方法,该方法采用 非常量 Bla,你不能通过它 常量布拉。所以现在你被卡住了。那么你 逐渐需要一个 const 版本的 所有不是 const 的东西,而你 以阴影世界告终。在 C++ 中,你 摆脱它,因为与 C++ 中的任何内容都是可选的 不管你是否想要这个检查。 你可以把常事打掉 如果你不喜欢它。

            见:http://www.artima.com/intv/choicesP.html

            所以,为什么 const 在 C++ 中起作用是因为你可以解决它。这对于源于 C 的 C++ 来说是明智的。

            对于 Java 和 C# 等托管语言,用户希望 const 与垃圾收集器一样安全。这也意味着您无法解决它,如果您无法解决它,它将没有用。

            【讨论】:

            • 那家伙显然不懂 C++。确实可以抛弃 const,但实际上很少这样做。
            • @DeadMG:如果我在谷歌代码搜索中搜索,我会得到 32000 次 const_cast 的点击。作为基准:dynamic_cast 接近 60000。所以认为需要 const_cast 的不仅仅是我和安德斯。
            • 需要不等于想要有关它的信息,或者认为您不需要它时需要它。搜索引擎中的结果数量是一个非常非常不相关的指标。如果你 grep 了 500 万行代码并发现它经常发生,那就不一样了。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-05-15
            • 2014-06-09
            • 2011-04-12
            • 2019-07-15
            • 2015-11-26
            • 2011-08-27
            • 1970-01-01
            相关资源
            最近更新 更多