这两个类都支持封装和......?

Suh*_*pta 2 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 void main(String args[]) {
      Normal normal = new Normal();
      normal.setName("suhail gupta");
      System.out.println( "My name is : " + normal.getName() );    
  }
 } 
Run Code Online (Sandbox Code Playgroud)

新课程从这里开始

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() );    
  }
 } 
Run Code Online (Sandbox Code Playgroud)

第一类的名称声明为public,其他类的名称声明为private.这两个类都做同样的工作,但只有名称不同的访问说明符.现在,

我的问题是?

  • 这两个类都支持封装吗?如果他们这样做,为什么private首选public(我做了同样的工作,声明公开名称,因为我已经宣布了private)
  • 哪个类更容易维护?
  • 哪个班级程序员会放心refactoring
  • 如何normal类不同,从different类?
  • 当他们说Unencapsulated意味着不可改变时,它是如何在这里不变的?

Nic*_*las 5

在" Normal"(没有什么"正常"),这是完全合法的代码:

public static void main(String args[]) {
   Normal normal = new Normal();
   normal.name = "suhail gupta";
   System.out.println( "My name is : " + normal.name );    
}
Run Code Online (Sandbox Code Playgroud)

您的界面现在包含一个String名为的值name.用户希望能够使用VarName.name或VarName.setName语法进行设置.用户希望能够使用VarName.name或VarName.getName检索它;

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

public static void main(String args[]) {
   Normal normal = new Normal();
   normal.name = null;
   String name = normal.name;
   System.out.println( "My name is : " + name );
}
Run Code Online (Sandbox Code Playgroud)

现在,也许你会想到"那么什么?" 想象一下,如果将变量设置为null,则将实际打印(发生错误的位置)与30个文件分开.很难知道谁搞砸了那个变量的价值.还有的没有什么可以做,以防止用户拧起来.

现在,如果您已实现setName如下:

public String setName(String newName) {
   assert newName;
   name = newName ;
   return name ;
}
Run Code Online (Sandbox Code Playgroud)

然后,在用户做错事后立即发生错误.用户尝试将值设置为null,不允许为null,因此出错.你有一个调用堆栈,显示错误发生的位置,这更容易调试.

当然,这并没有帮助,因为"用户Normal"不使用setName.他们可以name直接自由戳.

虽然它在技术上可能是封装,但就我而言,如果用户可以轻易地和平凡地颠覆它,那么它不是封装.如果没有保护,就没有封装.


当他们说Unencapsulated意味着不可改变时,它是如何在这里不变的?

好吧,假设您给我一个包含的库Normal.我将以某种方式使用它.也许我的Normal实例分散在50个文件中.它们直接设置并通过name访问者而不是访问者获取名称.这是完全合法的,因为你做到了public.

现在,无论出于何种原因,您决定不希望将名称存储在字符串中.也许你需要能够拥有名字和姓氏.所以,让我们说你的库的下一个版本有这个定义:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

少了什么东西?public String name;这已不再可用,因为您现在拥有名字和姓氏.请注意,这两个存取方法并没有改变在所有.

当我升级到您的库的新版本时,您将完全破坏我的所有代码.我不喜欢我的代码被破坏只是因为你决定改变你在班级中存储数据的方式.我现在永远不会再使用你制作的任何东西了,因为你甚至不能保持你的界面从一个版本到另一个版本的一致性.

如果你刚刚做好了事情,那一切都不会发生.