关于Java、C#、C++和PHP中访问级别的一个常见误解是,它适用于对象而不是类。也就是说,例如,类X的对象不能看到另一个X的私有成员。实际上,访问级别是基于类的,一个X对象可以轻松地引用另一个X的私有成员。
是否存在一种语言具有基于对象的访问级别?它们是替代还是附加于基于类的访问级别?这个特性对程序设计有什么影响?
是否存在一种语言具有基于对象的访问级别?它们是替代还是附加于基于类的访问级别?这个特性对程序设计有什么影响?
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)
没有一种语言在语义层面上支持这一点的主要原因是各种需求太不同了,很难找到一个足够大的共同点来支持这样的特性。数据隐藏本身已经够糟糕了,当你需要更精细的控制时,情况只会变得更糟。
这样的语言有优势,例如,您可以将某些数据标记为私有,除了创建它的对象之外,任何人都无法访问(密码就是一个很好的例子:即使在同一应用程序中运行的代码也无法读取它们)。
不幸的是,这种“保护”只是表面的,因为在汇编级别上,保护并不存在。为了高效,硬件需要支持它。在这种情况下,可能是在 RAM 中的单个字节级别上。这将使这样的应用程序非常安全,但速度极慢。
在现实世界中,您会在主板上的 TPM 芯片 中找到它,在 CPU 的 MMU 表中以非常粗略的形式出现。但这是在 4K 页面级别上,而不是在字节级别上。虽然有处理两者的库,但在我看来这并不算“语言支持”。
Java 有类似于 Security API 的东西。你必须用守卫来包装相关代码,询问当前的SecuityManager
是否允许访问。__setattr__
和 __getattr__
来实现类似的功能以进行字段访问。