gpt4 book ai didi

java - 面向对象访问说明符背后的推理

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:33:59 25 4
gpt4 key购买 nike

我有一个关于面向对象访问说明符的原因的一般性问题。我从来没有完全理解它们存在的原因,只是认为它们是作为一种非常基本的代码安全形式存在的,但是在查看了这个线程上的讨论之后

Does Python have “private” variables in classes?

我明白我完全错了,他们根本没有帮助安全。那么访问说明符只是被认为是面向对象设计中的良好编程实践吗?当我们说 private 或 protected 时,这究竟是谁在保护数据字段、类或方法?人们是否仍然可以访问已经知道的方法?通过反射等方式?

如果这个问题看起来很基础或有点元循环,我深表歉意,但它一直困扰着我,因为我不太清楚封装的主要 OOP 概念之一的确切原因。

最佳答案

访问修饰符用于指示调用者如何使用您的代码。当您维护内部状态时,它们尤其重要。考虑一个保持计数的类:

public class Thing {
public int count = 0;
public void doSomething() { count++; }
public int getHowManyTimesDone() { return count; }
}

这段代码有什么问题?如果调用者修改了 count,我的代码就违反了它的约定:

Thing x = new Thing();
x.doSomething();
x.doSomething();
x.count = 0;
System.out.println(x.getHowManyTimesDone());

我类(class)的契约说这应该打印 2,但它打印了 0,因为调用者修改了 count。通过使 count 成为一个 private 变量,我告诉调用者,“嘿,你不应该碰这个!这样做可能会破坏这段代码!”

Python doesn't have a concept of privacy 。相反,按照惯例,变量前加一个下划线会向调用者发出相同的警告:“如果你触摸它,它可能会破坏这段代码!”这可能与 protected 最相似。双下划线也会触发名称重整,这表明即使是子类也不应该使用它;这最类似于 private。在 Python 中,调用者有责任接受访问这些成员的风险,但鼓励程序员尽可能公开。

至于谁在Java中实现变量的可见性,那就是运行时本身。不过,确实有一些聪明的方法可以解决这个问题。我相信反射提供了一些方法,任何进入字节码或 JVM 本身的人都可以做一些事情。考虑一下 mock 所做的事情;他们可以说服 JVM mock 是一种特定类型,即使它不是。

编辑:

还有一件事。在 Java 中,鼓励程序员保持所有实例变量 private 并使用方法来访问和改变它们。这是为了可维护性,而不是出于隐藏细节的哲学原因。因为 Java 没有类似于 C# 或 Python 的属性机制,所以如果您需要向实例变量的获取或设置添加逻辑,则需要修改依赖于该实例变量的所有代码以使用这些方法。通过始终使用方法来访问变量,您可以最大限度地减少因进行此类更改而破坏的相关代码。换句话说,这是处理语言中的一个缺点的一种拼凑。

关于java - 面向对象访问说明符背后的推理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18168410/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com