私有方法优于公共方法

29

我正在研究 StringTokenizer.java 类,脑海中浮现出一些问题。

我注意到这些供其他类使用的公共方法调用了某些私有方法来完成所有工作。现在,我知道面向对象设计的原则之一是尽可能将许多内容设为私有并隐藏所有实现细节。但我不确定完全理解其中的逻辑。

我明白将字段设为私有很重要,以防止存储无效值(其中之一)。然而,当涉及到私有方法时,我不确定它们为什么如此重要。

例如,在 StringTokenizer 类的情况下,我们不能只将所有实现代码放在公共方法中吗?对于使用这些方法的类,它会有什么区别,因为这些方法的 API (即调用这些公共方法的规则)仍然相同?我唯一能想到私有方法有用的原因是它可以帮助您避免编写重复代码。例如,如果所有公共方法都执行相同的任务,则可以声明一个执行此任务的私有方法,并可以由公共方法使用。

另一个问题是,将实现写入私有方法与公共方法相比的优点是什么?

以下是一个小例子:

public class Sum{

    private int sum(int a, int b){
        return a+b;
    }

    public int getSum(int a, int b){
        return sum(a,b);
    }
}

对于C++开发人员来说,使用Visual Studio是非常常见的。

然而,有时候在创建新项目时,可能会遇到"无法打开包括文件..."的错误消息,这通常是由于缺少必要的头文件或库文件引起的。

为了解决这个问题,可以通过添加正确的目录路径或者安装缺失的组件来解决。

public class Sum{

    public int getSum(int a, int b){
        return a+b;
    }
}

第一个示例有什么好处?

7个回答

34
为了添加某些内容,私有方法始终可以安全更改,因为您确定它仅从本类调用,外部类无法调用私有方法(甚至无法看到它)。
因此,拥有私有方法总是很好的选择,因为您知道更改它没有问题,甚至可以安全地向该方法添加更多参数。
现在考虑公共方法,任何人都可以调用该方法,因此如果您添加/删除参数,则还需要更改对该方法的所有调用。

1
我不太明白您的意思,如果我有所遗漏请原谅。您说:“拥有一个私有方法总是好的,因为您知道更改它没有任何问题,甚至可以安全地向该方法添加更多参数。”但是,面向客户端的公共API仍然是相同的。因此,您可以在公共方法内编写所有逻辑或调用其中的函数,或者按照客户端查看公共API的方式进行操作,但是,实现中的代码仍然可以随时更改,这与更改私有函数的约定/实现一样好。 - Saurabh
在这种特定情况下,是的,它是相同的API,但你仍然不能保证它将来会保持不变。从我的经验中,我可以建议你不要采用“哦,让我们直接公开,如果将来需要私有化,我们会更改它”的想法,因为这样的方法永远不会变成私有的,所以最好在开始时进行一点过度架构,而不是最终进行大规模重构。 - Juan Antonio Gomez Moriano
如果一个公共方法调用了你更改的私有方法“没有问题”,那么公共方法是否仍然会出错?如果是这样,那么“安全更改”任何内容实际上并没有什么区别;无论你更改什么都必须进行测试 - 将其设置为公共/私有不会在这方面提供任何额外的安全性。 - gented

2

私有方法有用的唯一原因是它可以帮助你避免编写重复代码。

除了整合重复代码(通常表现为“不要重复自己”或“DRY”),使用私有方法还可以帮助您构建和记录代码结构。如果您发现自己正在编写一个执行多个任务的方法,您可以考虑将其拆分为几个私有方法。这样做可能会更清晰地说明每个逻辑片段的输入和输出(在更细粒度上)。另外,描述性的方法名称可以帮助补充代码文档。


1
是的,我同意你的观点。我想问的问题是,相比于公共方法,将实现代码编写为私有方法有什么好处?如果我们将所有代码放在公共方法中,这会有什么不同吗?本质上,我们仍然以相同的方式调用公共方法,并且仍然期望它返回与之前相同的结果。 - lbj-ub
3
保持代码私有能隐藏实现细节,使得实现可以改变而不会影响API的使用者。封装程度往往是任意的(有时甚至是随意的)。 - Dave Newton

1
声明方法为私有的目的是为了:
  • 隐藏实现细节
  • 将该方法排除在公共API列表之外
  • 确保代码背后的逻辑不会被外部使用/滥用
  • 大多数情况下,您的方法的执行依赖于其他方法先运行;然后您也可以确保控制正确的使用方法顺序
除非您打算让您的方法在类的上下文之外安全地使用,否则请使用private。

1
在编写Java或任何其他面向对象的语言的干净代码时,通常最清洁、最易读的代码由简短而简洁的方法组成。通常会出现这样的情况:方法内的逻辑可以通过调用多个单独的方法来更好地表达,从而使代码更加清晰和易于维护。
考虑到这一点,我们可以想象出许多方法朝着一个共同的目标执行任务的情况。想象一个只有一个复杂目的的类。该单一目标的入口可能只需要一个起始点(一个公共方法),但还需要许多其他方法作为复杂操作的一部分(许多私有辅助方法)。
使用私有方法,我们能够隐藏不应从类本身之外的任何地方访问的逻辑。

1

公共方法通常是其他实现该类的类想要使用的代码。私有方法通常在类外部不太有用,或者不能单独完成类的目标。

假设你正在使用你喜欢的IDE,并实现了一个名为A的类。A类只设计用于一件事情,比如文档生成。自然地,你会在A类中包含一些数学和字节操作方法,这些方法是生成文档所必需的,但是尝试使用A类的人不需要这些其他方法,因为他们只想要一个文档。因此,我们将这些方法设置为私有,以便未来使用我们类的用户能够更简单地使用。


0
在公共类中使用私有方法的一个好处和充分理由是为了安全和防止错误。声明为私有的方法只能被它们所属的类访问。这意味着你的私有方法不能被程序中其他地方意外调用,从而减少了错误和其他问题的发生。如果将方法声明为public,则整个程序都可以访问它,并可能引起复杂性。
您可能有许多处理某些数据的方法,而您不希望程序中的任何其他部分能够干扰。使用通过私有方法和/或变量进行数据封装可帮助防止此情况的发生,同时使您的代码更易于追踪和记录。

0

将函数设为私有的优点有:

  1. 将函数设为私有的优点是,JVM编译器可以选择内联函数,从而提高应用程序的性能。
  2. 如果类是可继承的,并且你从一个子类继承它,在需要隐藏子类中的函数时,你可以这样做(你可以扩展StringTokenizer)。
  3. 如果一段代码要在多个函数中使用,那么就将该代码移动到私有实用方法中。

你的#3不是private的优点;共享代码可以是公共的也可以是私有的。 - Dave Newton
好的,为了进一步解释我的观点,假设您有一组算法实现函数(全部公共)。现在,如果您的不同API需要计算两个数字平方和的平方根,则最好将此逻辑移动到一个以两个数字作为输入的私有函数中。将这样的函数设置为公共可能没有太多意义,因为您的类正在为不同级别的算法问题提供解决方案。将这样的函数设置为公共可能会违背该类的定义。 - Saurabh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接