4

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

私有(或类私有)限制对类本身的访问。只有属于同一类的方法才能访问私有成员。

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: 谢谢你们,所有的答案都非常有启发性......

到现在,暂时的结论

实例私有概念存在于 2 种语言中:

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

对象持有的状态始终是该对象私有的。其他对象只能通过向对象发送请求(消息)来查询或更改该状态。

2 - Ruby感谢洛根

有人总结了这些区别,他说在 C++ 中,“private”的意思是“这个类的私有”,而在 Ruby 中,它的意思是“这个实例的私有”。这意味着,在 C++ 中的 A 类代码中,您可以访问任何其他 A 类型对象的私有方法。在 Ruby 中,您不能:您只能访问您的对象实例的私有方法,而不能访问任何其他对象的私有方法对象实例(A 类)。

4

7 回答 7

3

在 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

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

于 2009-12-28T17:34:34.940 回答
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
    }
    ...
}

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

于 2009-12-28T17:16:22.307 回答
2

经过几个小时的谷歌搜索:)我发现了这个概念背后的语言:Smalltalk

对象持有的状态始终是该对象私有的。其他对象只能通过向对象发送请求(消息)来查询或更改该状态。

于 2009-12-28T20:56:37.970 回答
1

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

于 2009-12-28T16:59:20.533 回答
0

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

于 2009-12-28T16:58:19.177 回答
0

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

class Secretive { }
Secretive s = new Secretive() {
    int unknowable = 42;
};
Secretive t = new Secretive() {
    String unfathomable = "banana";
};
于 2009-12-28T17:04:51.680 回答
0
    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;
        }
    }

只需使用属性只读字段来强制执行您的安全性

您还可以使用内部访问器将您的类封装在 assambley 中。

您还可以使用一些像这样的拒绝技术。

于 2009-12-28T17:12:48.040 回答