为啥同一类而不是同一对象可以访问受保护和私有属性?

Posted

技术标签:

【中文标题】为啥同一类而不是同一对象可以访问受保护和私有属性?【英文标题】:Why protected and private attributes are accessible by same class rather than by the same object?为什么同一类而不是同一对象可以访问受保护和私有属性? 【发布时间】:2011-04-22 12:28:42 【问题描述】:

例如,我们有类Man

如果Man.age 受到保护,那么我不明白为什么chuckNorris(类Man)可以更改对象age(类@ 的另一个实例)的受保护/私有属性age 987654327@)。他不应该这样做(IMO)。

在我看来,protected/private 属性的 value 应该只属于 object 本身,而不属于 class。 ..

我想我需要一些解释,我很困惑。

【问题讨论】:

您的声明是否正确取决于编程语言/平台。我们在谈论什么语言或平台? Java ? php ?有什么区别吗? 我不熟悉 PHP。但我很确定 Java、C++、Smalltalk 和 Eiffel 在成员访问方面存在差异。 【参考方案1】:

马蒂厄是对的。 cuckNorris 可以做 jackBauer.age

但这没有问题。如果您在 Man 中引用 Man 实例属性,则意味着您正在编写 Man 类,因此您知道自己在做什么。

问题是,如果您将 Man 类传递给我,我可以在不知道 Man 类是如何编码的情况下访问 Man 属性。

Setter 和 getter 可能正在做一些我不知道也不需要知道的业务逻辑。但是给妈妈编码的人确实知道。

【讨论】:

【参考方案2】:

考虑这个 Java 类:

public class Base 
  private int a
  protected int b;

  public Base(int a,int b) 
    this.a = a;
    this.b = b;
  

  public int getA() 
     return a;
  

  public int getB() 
    return b;
   


...
 Base foo = new Base(1,2);
 Base bar = new Base(3,4);

没有办法(可能除了通过脏反射)foo 实例可以更改 bar 中的受保护或私有变量

如果你愿意,你可以允许它,

public class Base 
  private int a
  protected int b;

  public Base(int a,int b) 
    this.a = a;
    this.b = b;
  

  public int getA() 
     return a;
  

  public int getB() 
    return b;
   
 public void changeB(int newB,Base other) 
   other.b = newB;
 

... 
Base foo = new Base(1,2);
Base bar = new Base(3,4);
foo.changeB(5,bar);

您不能保护changeB 方法不改变other 对象[*] 中的内容,您只需要小心您的程序所做的事情。对于某些语言,您可以将 other 参数标记为 unchangeable ,但在 Java 中则不然 - 我觉得这没什么大不了的。

[*您可以通过将Base 的所有字段标记为最终字段,尽管在构造对象后,即使实例本身也无法更改成员。

【讨论】:

好的,谢谢,很清楚。而且我认为这很奇怪,即使 b 是私有的, foo 也可以更改 bar.b 。我的意思是私有应该与实例相关,而不是类。【参考方案3】:

私有属性只能通过类中的方法访问。 受保护的属性只能在后代类中访问。因此,对象jackbauer 不能修改Man 类对象chuckNorris 中的任何私有或受保护的内容。希望这会有所帮助

【讨论】:

你说“私有属性只能通过类中的方法访问”,那么如果jackBauer和chuckNorris都是Man类的对象,那么它们可以共享私有属性?? 在这种情况下,它将是一个由类的所有对象共享的类属性。这些属性是由静态一词设计的。 不,我不是在谈论静态属性,在对象chuckNorris里面我可以做到:jackBauer.age。而且我认为这很奇怪,因为这是一个私有属性,所以其他对象不应该能够读取或修改它。我错了吗? 你能给我一个代码示例吗?除非您有年龄的公共 setter 函数,否则您不能这样做。

以上是关于为啥同一类而不是同一对象可以访问受保护和私有属性?的主要内容,如果未能解决你的问题,请参考以下文章

澄清 Ruby 中“私有”和“受保护”的定义?

在 Java 中,为啥可以从同一个包中的类外部访问受保护的成员? [复制]

JavaSE8基础 同一个类下可以访问 默认/私有/受保护/公有的方法

Java:受保护的,可见的[重复]

面向对象抽象封装

面向对象抽象封装