Java 数据隐藏的原因?

Java 数据隐藏的原因?,java,c++,oop,Java,C++,Oop,我对编程很陌生。有人能解释为什么数据隐藏是用oop语言实现的吗?如果客户端无法查看/更改我的代码,为什么我需要隐藏数据。我永远不会显示或使用这些数据。什么是值得隐藏的?这似乎是一个涉及广泛考虑的相当广泛的问题,但我将尝试解决几个问题: 确保您的客户可能无法查看或更改您的代码(如果您提供了完整的编译应用程序),但您和任何其他维护人员都可以。数据隐藏的目的是最小化数据和接口的每一级之间的交互点。这有助于编写和维护正确的代码 出于同样的原因,全局变量很难以正确的方式使用和维护,数据的使用越本地化,就越

我对编程很陌生。有人能解释为什么数据隐藏是用oop语言实现的吗?如果客户端无法查看/更改我的代码,为什么我需要隐藏数据。我永远不会显示或使用这些数据。什么是值得隐藏的?

这似乎是一个涉及广泛考虑的相当广泛的问题,但我将尝试解决几个问题:

确保您的客户可能无法查看或更改您的代码(如果您提供了完整的编译应用程序),但您和任何其他维护人员都可以。数据隐藏的目的是最小化数据和接口的每一级之间的交互点。这有助于编写和维护正确的代码

出于同样的原因,全局变量很难以正确的方式使用和维护,数据的使用越本地化,就越容易摸索代码并对正确性充满信心


当您为一个类提供抽象接口时,您允许该类对其内部数据/状态进行操作,而外部世界不需要知道任何有关所使用的底层数据结构、类型或算法的信息。这将使您的代码更加简单,便于客户有效地使用。

这似乎是一个涉及广泛考虑的问题,但我将尝试解决以下几个问题:

确保您的客户可能无法查看或更改您的代码(如果您提供了完整的编译应用程序),但您和任何其他维护人员都可以。数据隐藏的目的是最小化数据和接口的每一级之间的交互点。这有助于编写和维护正确的代码

出于同样的原因,全局变量很难以正确的方式使用和维护,数据的使用越本地化,就越容易摸索代码并对正确性充满信心


当您为一个类提供抽象接口时,您允许该类对其内部数据/状态进行操作,而外部世界不需要知道任何有关所使用的底层数据结构、类型或算法的信息。这将使您的代码更加简单,便于客户端有效地使用。

这是关于复杂性的。以你汽车的发动机为例。这是一个非常复杂的物体。你可以,如果你知道的足够多的话,去那里玩弄东西,操作汽车。然而,这将是非常危险的。你也许可以做一些引擎设计师不想做的事情

在这个疯狂的场景中,您会得到一个接口。这是驾驶员的位置,方向盘、齿轮、踏板等。在这个位置上,您可以做的事情是受限的、安全的,驾驶汽车很容易。例如,您不能在未踩下制动踏板的情况下将档位换出驻车档。如果我绕过接口,直接进入引擎,我可能能够做任何事情,即使这会导致引擎的破坏

将这个应用到软件中,如果你有一个由2个整数值组成的分数类:一个分子和分母。有一个类不变量(规则)说:分母不能是0。如果分母恰好为0,那么分数对象将毫无意义,也将毫无用处。在以下代码中,我没有隐藏变量:

   public class Fraction{
         int numerator;
         int denominator;

         public Fraction add(Fraction f){
             //add this Fraction to f
         }

         ....
   }
在这种情况下,客户端代码可以执行以下操作:

    Fraction f1 = new Fraction();
    f1.numerator = 2;
    f1.denominator = 0;

    Fraction f2 = new Fraction();
    f2.numerator = 3;
    f2.denominator = 4;

    Fraction f3 = f1.add(f2);
你的add方法在这里做什么?此代码所做的是向客户提供确保避免此类问题的责任。通过适当的封装,确保所有对象完整性的责任属于类本身

  public class Fraction{
       private int numerator;
       private int denominator;

       public void setDenominator(int d) throws IllegalArgumentException{
             if(d == 0){
                 throw new IllegalArgumentExcepton("Denominator cannot be 0");
             }
             this.denominator = d;
       }
      ...
  }
如果客户端尝试执行此操作:

    Fraction f1 = new Fraction();
    f1.setDenominator(0); ///exception
每个人都很安全

因此,总结一下:

  • 使您的对象安全-客户端不能做您不想做的事情
  • 使对象更易于使用-客户端不需要知道类的所有内部工作就可以使用它
  • 有助于代码的可重用性—如果您决定更改类的实现,只要您不更改接口,客户端就不会受到影响

    • 这是关于复杂性的。以你汽车的发动机为例。这是一个非常复杂的物体。你可以,如果你知道的足够多的话,去那里玩弄东西,操作汽车。然而,这将是非常危险的。你也许可以做一些引擎设计师不想做的事情

      在这个疯狂的场景中,您会得到一个接口。这是驾驶员的位置,方向盘、齿轮、踏板等。在这个位置上,您可以做的事情是受限的、安全的,驾驶汽车很容易。例如,您不能在未踩下制动踏板的情况下将档位换出驻车档。如果我绕过接口,直接进入引擎,我可能能够做任何事情,即使这会导致引擎的破坏

      将这个应用到软件中,如果你有一个由2个整数值组成的分数类:一个分子和分母。有一个类不变量(规则)说:分母不能是0。如果分母恰好为0,那么分数对象将毫无意义,也将毫无用处。在以下代码中,我没有隐藏变量:

         public class Fraction{
               int numerator;
               int denominator;
      
               public Fraction add(Fraction f){
                   //add this Fraction to f
               }
      
               ....
         }
      
      在这种情况下,客户端代码可以执行以下操作:

          Fraction f1 = new Fraction();
          f1.numerator = 2;
          f1.denominator = 0;
      
          Fraction f2 = new Fraction();
          f2.numerator = 3;
          f2.denominator = 4;
      
          Fraction f3 = f1.add(f2);
      
      你的add方法在这里做什么?此代码所做的是向客户提供确保避免此类问题的责任。通过适当的封装,确保所有对象完整性的责任属于类本身

        public class Fraction{
             private int numerator;
             private int denominator;
      
             public void setDenominator(int d) throws IllegalArgumentException{
                   if(d == 0){
                       throw new IllegalArgumentExcepton("Denominator cannot be 0");
                   }
                   this.denominator = d;
             }
            ...
        }
      
      如果客户端尝试执行此操作:

          Fraction f1 = new Fraction();
          f1.setDenominator(0); ///exception
      
      每个人都很安全

      因此,总结一下:

      • 使您的对象安全-客户端不能做您不想做的事情
      • 使对象更易于使用-客户端不需要知道类的所有内部工作就可以使用它
      • 有助于代码的重用性—如果您决定更改类的实现,只要您不更改