是否有一种语言具有基于对象的访问级别?

发布于 2024-07-30 09:19:04 字数 216 浏览 4 评论 0原文

关于 Java、C#、C++ 和 PHP 中的访问级别的一个常见误解是它适用于对象而不是类。 也就是说,(比如说)类 X 的对象无法看到另一个 X 的私有成员。 当然,事实上,访问级别是基于类的,一个 X 对象可以毫不费力地引用另一个 X 对象的私有成员。

是否存在一种具有基于对象的访问级别的语言? 它们是替代基于类的访问还是除了基于类的访问之外? 这个功能对程序设计有什么影响?

A common misconception about access level in Java, C#, C++ and PHP is that it applies to objects rather than classes. That is, that (say) an object of class X can't see another X's private members. In fact, of course, access level is class-based and one X object can effortlessly refer to the private members of another.

Does there exist a language with object-based access levels? Are they instead of, or in addition to, class-based access? What impact does this feature have on program design?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

假装不在乎 2024-08-06 09:19:04

Ruby 具有基于对象的访问级别。 以下是《Ruby 编程》中的引文:

“受保护”和“受保护”的区别
而“私人”是相当微妙的,并且
Ruby 中的情况与大多数情况有所不同
常见的面向对象语言。 如果一个方法是
受保护,它可以被任何调用
定义类或其实例
子类。 如果一个方法是私有的,那么它
只能在上下文中调用
调用对象的——它永远不会
可以访问另一个对象的
直接私有方法,即使
对象与该对象属于同一类
来电者。

这是来源: http://whytheluckystiff.net/ruby/pickaxe/html /tut_classes.html#S4

Java 和 Ruby 之间的差异示例

Java

public class Main {
    public static void main(String[] args) {
        Main.A a1 = new A();
        Main.A a2 = new A();

        System.out.println(a1.foo(a2));
    }

    static class A
    {
        public String foo(A other_a)
        {
            return other_a.bar();
        }

        private String bar()
        {
            return "bar is private";
        }
    }
}

// Outputs
// "bar is private"

Ruby

class A
  def foo other_a
    other_a.bar
  end

  private
  def bar
    "bar is private"
  end
end

a1 = A.new
a2 = A.new

puts a1.foo(a2)

# outputs something like
# in `foo': private method `bar' called for #<A:0x2ce9f44> (NoMethodError)

Ruby has object-based access level. Here's a citation from Programming Ruby:

The difference between "protected"
and "private" is fairly subtle, and
is different in Ruby than in most
common OO languages. If a method is
protected, it may be called by any
instance of the defining class or its
subclasses. If a method is private, it
may be called only within the context
of the calling object---it is never
possible to access another object's
private methods directly, even if the
object is of the same class as the
caller.

And here's the source: http://whytheluckystiff.net/ruby/pickaxe/html/tut_classes.html#S4

Example difference between Java and Ruby

Java

public class Main {
    public static void main(String[] args) {
        Main.A a1 = new A();
        Main.A a2 = new A();

        System.out.println(a1.foo(a2));
    }

    static class A
    {
        public String foo(A other_a)
        {
            return other_a.bar();
        }

        private String bar()
        {
            return "bar is private";
        }
    }
}

// Outputs
// "bar is private"

Ruby

class A
  def foo other_a
    other_a.bar
  end

  private
  def bar
    "bar is private"
  end
end

a1 = A.new
a2 = A.new

puts a1.foo(a2)

# outputs something like
# in `foo': private method `bar' called for #<A:0x2ce9f44> (NoMethodError)
埋情葬爱 2024-08-06 09:19:04

没有语言在语义层面支持这一点的主要原因是,各种需求差异太大,无法找到一个足够大的共同点来支持这样的功能。 数据隐藏本身就已经够糟糕的了,当您需要更细粒度的控制时,情况只会变得更糟。

这种语言会有很多优点,例如,您可以将某些数据标记为除创建它的对象之外的任何人的私有数据(密码就是一个很好的例子:即使在同一应用程序中运行的代码也无法读取它们)。

不幸的是,这种“保护”是肤浅的,因为在汇编器级别,这种保护是不存在的。 为了高效,硬件需要支持它。 在这种情况下,可能是 RAM 中单个字节的级别。 这将使这样的应用程序变得极其安全并且速度极其缓慢。

在现实世界中,您会在主板上的 TPM 芯片 中找到它,并且在一种非常粗略的形式,带有 CPU 的 MMU 表。 但这是在 4K 页面级别,而不是字节级别。 有一些库可以处理这两种情况,但这不算是“语言支持”IMO。

Java 以 安全 API。 您必须将有问题的代码包装在监护程序中,该监护程序询问当前 SecuityManager 是否允许访问。

在Python中,您可以使用装饰器(对于方法和函数)或通过实现__setattr____getattr__来实现字段访问。

The main reason why no language has support for this at the semantic level is that the various needs are too different to find a common denominator that is big enough for such a feature. Data hiding is bad enough as it is, and it gets only worse when you need even more fine grained control.

There would be advantages to such a language, for example, you could mark certain data as private for anyone but the object which created it (passwords would be a great example: Not even code running in the same application could read them).

Unfortunately, this "protection" would be superficial since at the assembler level, the protection wouldn't exist. In order to be efficient, the hardware would need to support it. In this case, probably at the level of a single byte in RAM. That would make such an application extremely secure and painfully slow.

In the real world, you'll find this in the TPM chip on your mainboard and, in a very coarse form, with the MMU tables of the CPU. But that's at a 4K page level, not at a byte level. There are libraries to handle both but that doesn't count as "language support" IMO.

Java has something like this in form of the Security API. You must wrap the code in question in a guardian which asks the current SecuityManager whether access is allowed or not.

In Python, you can achieve something similar with decorators (for methods and functions) or by implementing __setattr__ and __getattr__ for field access.

晚雾 2024-08-06 09:19:04

您可以在 C# 中实现此功能,方法是使用某种能够遍历堆栈并检查调用者是哪个对象的方法,如果它不是当前类,则抛出异常。 我不知道你为什么想要这么做,但我想我应该把它扔掉。

You could implement this in C# by having some method capable of walking the stack and checking which object the caller is, and throwing an exception if it's not the current class. I don't know why you would want to, but I thought I'd throw it out there.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文