【问题标题】:Public vs Private [duplicate]公共与私人[重复]
【发布时间】:2013-01-31 13:27:28
【问题描述】:

以下是我作为课程练习所做的 Java 代码。我有一个名为 SavingsAccount 的类。它有余额和利息变量。但是,我将它们设置为公开,但如果我想单独处理这些帐户,我是否需要将它们设为私有并为这些变量提供“获取/设置”方法?我可以不公开变量吗?其余代码具有使用这些变量进行计算的方法。

public class SavingsAccount { //This class has three different variables that define it
    public double balance; //Double for account balance
    public static double annualInterestRate; //Class method for interest rate
    public final int ACCOUNT_NUMBER; //Constant int for keeping track of accounts


public SavingsAccount (int ACCOUNT_NUMBER, double balance) { //Constructor that takes down account number and balance to keep track of
        this.ACCOUNT_NUMBER = ACCOUNT_NUMBER;
        this.balance = balance;
    }

【问题讨论】:

  • “单独处理帐户”与访问帐户数据的方式无关。
  • 我能问一下为什么这被否决了吗?我正在尝试了解有关封装的更多信息。
  • 我放了一个示例代码验证一个例子。那篇文章没有例子。不过没关系。
  • -1(我不是第一个反对投票的人,但我会证明我的投票是正确的)您似乎将访问修饰符与对象封装混淆了。访问修饰符用于限制从其他代码访问代码。对象封装是关于在类实例的范围内存储数据,通常使用静态成员和实例成员。
  • @JesseWebb "Encapsulation" 用于描述两种不同的事物:访问限制和数据/行为捆绑。 (例如,请参阅 Wikipedia 条目。)IMO 反对而不是讨论是一种相当直率的工具。对术语分歧的否决,特别是当它完全有效地使用该词时,太多了。

标签: java private public


【解决方案1】:

我认为可以指出两种不同的情况,您希望和不想使用公共字段。

第一个是当您使用不可变数据结构时。我完全相信不可变数据结构是您想要努力实现的目标。不可变结构的优缺点可以在其他地方找到;关于公共领域,不可变结构暗示了显而易见的事情 - 将所有领域公开。好吧,结构是不可变的,所以你只能读取值。在这种情况下,getter 是完全没有必要的,只会让你的代码变得混乱。

显然,第二个是当您使用可变结构时。在这种情况下,使用 getter 和 setter 是合理的;您完全有可能将一些逻辑放入 setter 中,并且在这里封装数据字段是必须的:您真的不希望有人意外更改您的数据。但是,我认为可变 DTO 是邪恶的,应该避免。我看到它们使用它们的唯一原因是与某些 API(如 Hibernate)的兼容性。

当它们包含您不希望任何人访问的内部状态时,您还应该隐藏字段。实现某些行为(服务、DAO 等)的类就是这种情况。在这种情况下,您通常甚至不想创建 getter 和 setter。

因此,简而言之,我会给出以下建议:使用具有公共字段的不可变对象作为您的 DTO,并使在这些 DTO 上工作的行为类尽可能封闭。

【讨论】:

    【解决方案2】:

    将其设为私有很好。假设我正在访问您的课程并设置如下值。

    SavingsAccount sa = new SavingsAccount(12345,25000);

    现在我可以直接使用对象设置我的余额,如下所示:

    sa.balance = -300;

    sa.ACCOUNT_NUMBER = 6789;

    您的班级没有提供任何安全措施。这就是 OOP 中的一个重要概念,称为数据封装。

    【讨论】:

      【解决方案3】:

      除非您在设置值时执行某种验证(即余额不是负数),否则请尽可能使用public

      为仅返回或分配值的属性创建 getter 和 setter,而无需额外的逻辑,实际上会将您的属性公开为 public 并为代码提供不必要的混乱(就可读性而言)。直接使用公共属性使代码更干净。

      示例 1:

      *您希望允许帐户仅具有正余额。每次分配值时,您都必须执行检查以查看是否为其分配了负值。

      执行此操作的最佳位置是在 setter 方法中。这使您摆脱了必须在各处放置大量if(newBalance < 0) 检查的麻烦。

      要强制执行您只需要正余额值这一事实,您可以创建属性private。这限制了可能想要为balance 属性(*) 分配负值的程序员。为了使 balance 属性中保存的值再次可访问,您需要为私有值添加一个 getter。

      您现在拥有“某种”public 属性,您可以对其实施限制(不能设置为否定)。

      示例 2:

      您想为每个帐户做笔记。您的班级中将有一个String notes; 属性。

      如果您不想强制执行任何限制,最好使用public 修饰符。

      考虑以下哪段代码更简洁:

      accountA.setNotes(accountB.getNotes());
      

      accountA.notes = accountB.notes;
      

      它们都将notes 从一个帐户复制到另一个帐户,但后者更易于阅读。

      【讨论】:

      • 除非绝对必要,否则您的字段不应公开
      • 同意——这违背了面向对象的概念。
      • -1 - 使用访问器和修改器的想法是允许您稍后更改实现,而无需更新一堆其他代码。例如,我可以更改一个简单的 setter 以包含验证。或者我可以更改一个 getter 以不再返回私有字段,而是执行计算。我会说“混乱”是值得的,特别是因为大多数 IDE 无论如何都会为您生成此代码。
      • 为了避免“混乱”,请查看project lombok
      • @JesseWebb 是的,这是 getter 和 setter 的另一种用途,我同意你的观点,但是看看问题中写的类,这是为了保存数据。为了更好地解释我试图解释的内容,Robin C. Martin 有一章很好地介绍了干净代码中的数据/对象反对称。 amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/…
      【解决方案4】:

      始终建议设置某些字段private 而不是public
      因为,使用正确的方法来访问它们可以提供简洁的代码和更少的错误。
      想想你自己,有人想知道你的帐号,以现金的方式给你礼物。
      你更喜欢什么 那个人会及时询问你并拿到你的空调。否或您公开宣布您的 A/c No. 并且此人在不通知您的情况下获得 A/c No.。
      第一个似乎是 private 并使用 get/set 方法。
      第二个似乎是public

      【讨论】:

        【解决方案5】:

        但是,我将它们设置为公开,但如果我想处理这些帐户 单独,我是否需要将它们设为私有并具有“获取/设置” 这些变量的方法?

        首先,您的类的每个实例都被视为一个单独的 SavingAccount。

        SavingAccount acct1 = new SavingAccount(....); //represents one Saveing account
        SavingAccount acct2 = new SavingAccount(....); //represents another Saveing account
        

        您的属性标记为公开还是私有并不重要。通常,如果你想封装你的类,你可以将你的属性设为私有并拥有公共的 getter/setter 方法,这样其他对象就不能直接访问你的属性。他们只能通过 getter/setter 访问它们。

        【讨论】:

          【解决方案6】:

          您当然可以将变量公开,但这里有很多人会为此追捕您...
          这是面向对象范式中encapsulation 的问题。一般来说,物体不能互相戳对方的内脏。

          【讨论】:

          • 使成员尽可能私密,并根据需要公开。
          • +1,那是你的世纪.. :)
          【解决方案7】:

          如果您将变量定义为 public,则它们可以直接访问/设置。
          如果将它们定义为私有,则需要 getter 和 setter。

          控制访问是可取的,将它们声明为私有的。

          【讨论】:

            【解决方案8】:

            数据封装设置私有字段是个好主意。数据封装是一种限制和控制对字段的访问以防止程序员进行不良操作的做法。如果你不这样做,程序员可能会以不受控制的方式访问或更改实例上的变量,这可能会破坏事情。换句话说,控制对变量的访问会使破坏和引入错误变得更加困难。

            基本上,您的课程应该像“黑匣子”一样工作。从外部看,另一个程序员看不到,也不关心内部(即私有字段)是如何工作的。您只能通过使用显式声明的操作(即公共方法)与框进行交互。这些操作将根据需要操纵内部结构。

            当然,你可以为所欲为。

            【讨论】:

              猜你喜欢
              • 2014-07-14
              • 2016-11-24
              • 2017-02-17
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-12-11
              • 2012-08-03
              • 2011-01-09
              相关资源
              最近更新 更多