【问题标题】:In which situations we make variables as public and methods as private?在哪些情况下,我们将变量设为公共而将方法设为私有?
【发布时间】:2013-06-21 06:44:42
【问题描述】:

目前我正在学习 java 和 C++ 的基础知识。我在Let Us C++一书中读到,几乎在每种情况下,出于安全目的,我们都会将实例变量设为私有而将方法设为公开。但本书中也提到,在某些情况下,我们将变量设为公共,将方法设为私有..

我一直在思考,在哪些情况下我们会这样做。谁能解释一下。

【问题讨论】:

  • 你总是需要一个用户不应该关心的类中的实用函数。如果您采用严格的功能做一件事的方法,那就太好了。
  • @chris,先生,您能举个例子吗?
  • 如果你在 C++ 中做一个单例,构造函数将是私有的
  • 请提高帖子质量(拼写、标点、句首大写字母等)。
  • @Spook,谢谢,下次我会记住的……

标签: java c++ oop


【解决方案1】:

私有方法(或 C++ 术语中的私有成员函数)最常用作辅助函数。例如,考虑一下您想要实现分数,但想要确保您的分数始终被标准化的情况。然后您可以使用私有成员函数normalize() 来规范化您的分数,并在每次可能导致非规范化分数的操作之后调用它,例如(C++ 代码):

class Fraction
{
public:
  Fraction(int num, int den = 1);
  Fraction operator+=(Fraction const& other);
  Fraction operator*=(Fraction const& other);
  // ...
private:
  int numerator, denominator;
};

Fraction::Fraction(int num, int den):
  numerator(num),
  denominator(den)
{
  normalize();
}

Fraction Fraction::operator+=(Fraction const& other)
{
  int new_den = denominator*other.denominator;
  numerator = numerator*other.denominator + denominator*other.numerator;
  denominator = new_den;
}

Fraction Fraction::operator*=(Fraction const& other)
{
  numerator *= other.numerator;
  denominator *= other.denominator;
  normalize();
}

void Fraction::normalize()
{
  int factor = gcd(numerator, denominator);
  numerator /= factor;
  denominator /= factor;
}

另外,C++ 对私有函数的特定使用是基于这样一个事实:在 C++ 中,私有仅与访问控制有关,与可见性无关。这样可以在基类中进行不可覆盖的前置条件检查,同时使实际函数为虚拟:

class Base
{
public:
  foo frobnicate(some arguments);
private:
  virtual foo do_frobnicate(some arguments) = 0;
};

foo Base::frobnicate(some arguments)
{
  check_precondition(arguments);
  foo result = do_frobnicate(arguments);
  check_post_condition(foo);
  return foo;
}

Base 派生的类将覆盖do_frobnicate,而用户将调用frobnicate,无论派生类做什么,它始终检查前置/后置条件。

【讨论】:

  • 公开一个变量怎么样?有什么理由这样做吗?
  • @petric 我的一般规则是所有变量都是公共的(结构),或者没有。在第一种情况下,为了方便,我可能会添加构造函数(无论如何,在 C++03 中 --- 在 C++11 中,统一的初始化语法在很大程度上消除了这种需要),我想我可能想要一个私有函数供这些构造函数使用(尽管它肯定不是很频繁)。
【解决方案2】:

通常静态最终变量在类中是公共的。如果您不需要更改该变量的值并希望其他类访问它,则将其设为 public static final。

私有方法仅在类中用于执行任务,这是该类内部的。像实用程序方法或某些业务计算方法。或者干脆把公共方法的代码分解成多个私有方法,这样方法就不会变得太大。

【讨论】:

    【解决方案3】:

    当一个方法要被该类的其他方法(公共)使用并且您不希望对象直接访问该方法时,我们将该方法设为私有。

    并且在某些情况下,如果您想直接从类对象访问您的变量,则将其设为公开。

    【讨论】:

      【解决方案4】:

      如果您不需要其他类中的变量或方法,请不要将其公开。这适用于方法和变量。

      【讨论】:

        【解决方案5】:

        私有方法供类的内部使用。可以从其他公共类调用它们。这些是私有的,因为你是从外部世界封装的。

        例如

        public void method1(){
            method2();
        }
        
        private void method2(){
            // for internal use
        }
        

        公共变量主要用于类变量,在这种情况下直接从外部访问变量是没有害处的。例如

        public static  final int FLAG = true;
        

        你可以直接从外部调用变量。

        【讨论】:

          【解决方案6】:

          这取决于您希望为每个班级提供多少安全性。

          例如,如果您有一个 Vector 类,它只有 3 个变量 x、y 和 z,您应该将它们公开。许多类可能会使用 Vector 类,如果它们更改其中的值就可以了。

          如果您有一个 Person 类来存储信用卡号、背景记录、地址等,您应该将它们设为私有以避免安全问题。

          但是,如果您将所有变量都设置为私有变量,并为所有变量提供访问器和修改器,那么您实际上将它们设为公共变量(但需要更多工作)。

          编辑: 所有常量变量都应该是公开的,因为无论如何您都无法更改它们。 静态变量可以是两者,这取决于具体情况。对静态变量使用静态 get 和 set 函数可能会更好。

          【讨论】:

          • 没有理由公开所有常量变量。它们可能是一个完全没有理由公开的实现细节。
          • 也没有理由保密!为什么要隐藏你无法改变的东西?
          • 重点是避免安全问题。没问题 - 不需要私有关键字。
          • 不,这根本不是重点。为什么要公开客户不需要的东西?
          • @ole_92 访问点说明符绝对不限于安全性,并且根据安全性的定义,无论如何它都非常不适合该目的。通过清楚地记录公共接口是什么,访问说明符还提供了更好的封装。
          【解决方案7】:

          私有变量或函数只能在声明它们的类中使用。

          公共变量或函数可以在您的应用程序中随处使用。

          因此,您应该在它们所属的类中声明您将使用的所有变量和函数。

          例子:

          public class Car {
              private String model;
          
              public setModel(String model) {
                  if (model != null)
                      this.model = model;
              }
          
              public getModel() {
                  return model;
              }
          
              private doSomething() {
                  model = "Ford";
              }
          }
          

          在 Car 类中,我们将 String 模型声明为私有,因为我们将只在 Car 类中使用它,这样做可以确保其他类在不使用函数 setModel 的情况下无法更改此 String 的值。

          函数 setModel 和 getModel 是公共的,因此我们只能使用这些方法从其他类访问私有变量模型。

          在此示例中,函数 setModel 检查值是否为 null,在这种情况下,它不会设置该值。在这里您可以看到,如果您将 String 模型声明为 public,您将无法控制它被记录的值。

          doSomething 函数是私有的,其他类不能使用它。另一方面,像这个函数是私有的,它属于String模型所在的同一个类,它可以在不使用setModel方法的情况下改变它的值。

          【讨论】:

            【解决方案8】:

            根据经验,当其他类可以访问它们时,您可以创建方法public。内部方法或辅助方法应该是 protectedprivate.Protected 如果您希望该方法可以被那些扩展您的类的人扩展,但是如果您不希望这样做,只需将它们标记为 private

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2013-06-08
              • 1970-01-01
              • 2015-06-09
              • 1970-01-01
              • 1970-01-01
              • 2012-09-15
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多