Java 这两个类都支持封装和。。。?

Java 这两个类都支持封装和。。。?,java,oop,encapsulation,Java,Oop,Encapsulation,新课程从这里开始 public class Normal { public string name; // name is public public String getName() { return name ; } public String setName(String newName) { name = newName ; return name ; } public static

新课程从这里开始

public class Normal {
   public string name;     // name is public

   public String getName() {
        return name ;
   }

   public  String setName(String newName) {
         name = newName ;
         return name ;
   }

   public static void main(String args[]) {
      Normal normal = new Normal();
      normal.setName("suhail gupta");
      System.out.println( "My name is : " + normal.getName() );    
  }
 } 
第一个类的名称声明为public,另一个类的名称声明为private。这两个类执行相同的工作,但只有不同名称的访问说明符。现在,

我的问题是什么

  • 这两个类都支持封装吗?如果是,为什么
    私人
    公共
    更受欢迎?(我在声明名称公共时所做的工作与声明
    私有时所做的工作相同)
  • 哪个类更容易维护
  • 重构过程中,哪些类程序员会感到轻松
  • normal
    类与
    类有何不同
  • 当他们说,这里怎么是不变的
      • getter和setter的思想是允许开发人员执行其他必需的逻辑来派生类字段的值。因此,将类字段保留为public允许在为该字段赋值之前跳过执行逻辑

      • 第二个类更易于维护,因为可以确保始终通过setter设置name变量的值

      • 同样,第二个类更适合于重新分解,因为它公开的成员更少

      • 如果您想象其他开发人员使用“normal”类,他可能会选择直接设置name的值,而不是使用setter。因此,如果将来您决定更改“name”变量的可见性,您将破坏其他人代码。在这样一个简单的示例中,这并不重要,但在编写重要代码时,这往往会出现问题,因为您不希望通过更改变量的可见性来破坏其他开发人员的代码。因此,未封装的代码是不可更改的

      一般来说,更好的设计往往会暴露较少的运动部件。但除此之外,封装还减少了类内部可由其他代码操作的方式

    • Different
      是一个比
      Normal
      更好的封装示例,尽管如此简单,其好处并不明显

    • Different
      在理论上更易于维护,因为如果要更改
      name
      的内部表示形式,可以在不修改公共API的情况下进行

    • 与#2相同,原因相同

    • 第一个类允许用户直接修改
      name
      ,第二个类则让用户通过
      getName()
      setName()

    • 如果某件东西是未封装的,那么你就是在向世界暴露所有的内在细节。这是很难的,如果不是不可能的话,追溯更改,因为您将破坏任何使用它的现有代码

    • 在“
      Normal
      ”(这一点不“正常”)中,这是完全合法的代码:

      public class Different {
         private string name;         // name is private
      
         public String getName() {
              return name ;
         }
      
         public  String setName(String newName) {
               name = newName ;
               return name ; 
         }
      
         public static void main(String args[]) {
            Different different = new Different();
            different.setName("suhail gupta");
            System.out.println( "My name is : " + different.getName() );    
        }
       } 
      
      您的界面现在包含一个名为
      name
      字符串
      值。用户希望能够使用VarName.name或VarName.setName语法进行设置。用户希望能够使用VarName.name或VarName.getName检索它

      例如,这在“
      Normal
      ”中是合法的:

      现在,您可能会想“那又怎样?”想象一下,如果将变量设置为null与实际打印(发生错误的地方)分开30个文件。很难知道是谁搞砸了这个变量的值。而且你无法阻止用户把它搞砸

      现在,如果您将
      setName
      实现为:

      public static void main(String args[]) {
         Normal normal = new Normal();
         normal.name = null;
         String name = normal.name;
         System.out.println( "My name is : " + name );
      }
      
      然后,当用户做错事时,错误立即发生。用户试图将不允许为null的值设置为null,因此出现错误。您有一个显示错误发生位置的调用堆栈,这更易于调试

      当然,这没有帮助,因为“
      Normal
      ”的用户不必使用
      setName
      。他们可以自由地直接戳
      名称

      虽然从技术上讲它可能是封装,但就我而言,如果用户可以轻松地破坏它,那么它就不是封装。如果没有保护,就没有封装


      当他们说未封装意味着不可更改时,在这里它是如何不可更改的

      好的,假设你给我一个包含
      Normal
      的库。我会以某种方式使用它。也许我的
      Normal
      实例分散在50个文件中。它们通过
      name
      而不是访问器直接设置和获取名称。这是完全合法的,因为你把它公开了

      现在,不管出于什么原因,您决定不将名称存储在字符串中。也许你需要有名字和姓氏。那么,假设您的库的下一个版本具有以下定义:

      public String setName(String newName) {
         assert newName;
         name = newName ;
         return name ;
      }
      
      少了什么<代码>公共字符串名称不再可用,因为您现在有了名字和姓氏。请注意,这两个访问器方法根本没有改变

      当我升级到您的库的新版本时,您将破坏我的所有代码。我不希望我的代码因为您决定更改在类中存储数据的方式而被破坏。我现在再也不会使用你做的任何东西了,因为你甚至不能让你的界面在不同版本之间保持一致


      如果你刚刚做得很好,这些都不会发生。

      @Maxpm不,我一直在努力找到令我满意的答案。.请看代码中的链接@Franklin这是oop问题java的几行代码并不能让它成为java问题,那么我将用代码回答它。。。这句话的几行并不能让它成为一个lolcode答案…@Franklin好的..试着回答我你会是什么样的人
      public String setName(String newName) {
         assert newName;
         name = newName ;
         return name ;
      }
      
      public class Normal
      {
          public string firstName;
          public string lastName;
      
          public String getName()
          {
              return firstName + " " + lastName;
          }
      
          public  String setName(String newName)
          {
              //parse newName into a first and last name.
              ...
              firstName = newFirstName;
              lastName = newLastName;
              return getName();
          }
      }