【问题标题】:object-private Vs class-private对象私有与类私有
【发布时间】:2010-12-30 12:49:36
【问题描述】:

在任何 OOP 语言中都有 object-private 的概念吗?我的意思是比经典的私人访问更严格?

Private (or class-private) restricts the access to the class itself. Only methods that are part of the same class can access private members.

object-private : 限制对对象本身的访问。只有可以访问成员的方法对象,并且无法编写:

public class Person {

private String secret;
public String othersSecret;

public void snoop(Person p) {
    othersSecret = p.secret; //will be prohibited by the compiler
}

编辑:

如果存在,您能给我一些例子吗?如果不存在,您认为拥有这种功能很有趣吗?是否可以用其他 OOP 语言模拟它??

编辑 2: 谢谢你们,所有的答案都非常有启发性......

到目前为止,暂时的结论

instance-private 概念存在于 2 种语言中:

1 - Smalltalk 经过数小时的谷歌搜索 :) 我找到了这个概念背后的语言!!

The state an object holds is always private to that object. Other objects can query or change that state only by sending requests (messages) to the object to do so.

2 - Ruby 感谢Logan

One person summed up the distinctions by saying that in C++, “private” means “private to this class”, while in Ruby it means “private to this instance”. What this means, in C++ from code in class A, you can access any private method for any other object of type A. In Ruby, you can not: you can only access private methods for your instance of object, and not for any other object instance (of class A).

【问题讨论】:

  • 我刚刚编辑了我的帖子以使其更加清晰......我询问了理论......在任何 OOP 语言中......
  • 是什么让我“嗯?”在 C# 上,AFAIK 它只支持私有类。
  • @Johannes : 'class-private' 是 OOP 语言(C#、java ...)处理封装的正常方式...直到现在我只看到允许'对象私有' ...
  • @wj:请随意将 Smalltalk 加入您自己的答案中。 meta.stackexchange.com/questions/12513/…
  • @outis:谢谢小费!我不知道是否有可能/建议回答我们自己的问题……下次会这样做;)

标签: ruby oop private encapsulation smalltalk


【解决方案1】:

在 ruby​​ 中,每个对象的私有是唯一私有的(您必须使用 protected 来获得类私有行为)。

例如foo.rb:

 class A
    private
    def a=(x)
            @a=x
    end
    public
    def a
            @a
    end

    def b(c)
            c.a = 2
    end
 end

 a1 = A.new
 a2 = A.new
 a1.b(a2)

运行它,我们得到

 foo.rb:12:in `b': private method `a=' called for #<A:0xb7c9b6e0> (NoMethodError)
    from foo.rb:18

当然有办法解决这个问题,但几乎总是有。

【讨论】:

  • 非常有趣的例子!!我想知道是否有其他语言支持这一点......以及为什么它不是其他 OOP 语言的标准......
  • 有各种各样的 OO 特性,只出现在某些语言中。一些有趣的东西见 CLOS(例如多方法、元类和方法组合(例如 :before、:after 和 :around),其中后两者预示着面向方面的编程)。
  • @outis:我最喜欢 CLOS 的地方是当我们使用 call-next-method 时,多重继承中调用的线性化......大到 CLOS ;)
【解决方案2】:

我认为你想要的功能可以通过形象地实现,不允许 Persons 直接通信。 为了以最少的努力实现这一点,您可以引入一个接口,该接口不会提供对您想要保密的内容的访问。

public interface IPerson
{
    void communicateFormally();
}

public class Person : IPerson 
{
    private String secret;
    public String othersSecret;

    public void snoop(IPerson p) {
      othersSecret = p.secret; //will be prohibited by the compiler
    }
    ...
}

现在,这可能会被一个丑陋的演员“破解”,但我认为这是一个黑客的问题。

【讨论】:

  • 但这会给我们一个“pivate-interface”功能......而不是像“Logan Capaldo”红宝石示例这样的“私有对象”......
【解决方案3】:

【讨论】:

【解决方案4】:

在 Java 中,就像您正在编写的那样,“私有”意味着类私有。没有办法强制对象私有模式。原因是“私有”是一种强制封装的方式,而不是安全

【讨论】:

    【解决方案5】:

    我不认为这种类与对象的区别private 存在于最常见的面向对象语言中,例如 C#、C++、Python、Java、Objective-C ... 公平地说,我不记得了实际上具有此功能的语言。

    【讨论】:

      【解决方案6】:

      是的,您可以在 Java 中创建包含该接口的其他实例无法看到的实例变量的对象。简单的例子:

      class Secretive { }
      Secretive s = new Secretive() {
          int unknowable = 42;
      };
      Secretive t = new Secretive() {
          String unfathomable = "banana";
      };
      

      【讨论】:

      • 这并不完全正确。在您的示例中,您创建了两个新的匿名类,并为每个类创建一个实例。因此,每个实例都可以拥有其(匿名)类私有的数据,但这与拥有实例私有的数据并不完全相同。
      【解决方案7】:
          public class Person
          {
              private String privateSecret;
              public String PublicInformation;
      
              public void Snoop(Person p)
              {
                  // will be allowed by the .NET compiler
                  p.PublicInformation = p.privateSecret;
              }
          }
      

      只需使用 propertiesreadonly 字段来强制您的安全性

      您还可以使用 internal 访问器将您的类封装在一个 assambley 中。

      您还可以使用一些拒绝技术,例如this one

      【讨论】:

      • javac 和我知道的所有 oop 编译器也将允许它......我问是否有一种语言提供其他级别的封装来禁止这种......
      • @Paolo :这不是“奇怪的”,而是 OOP 语言处理封装的正常方式......这就是我问我的问题的原因 :)
      猜你喜欢
      • 2020-10-25
      • 1970-01-01
      • 2014-06-19
      • 1970-01-01
      • 2022-01-22
      • 2022-11-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多