这两个类都支持封装和...吗? [英] Do both these classes support encapsulation and ...?

查看:75
本文介绍了这两个类都支持封装和...吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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 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 声明为public,另一堂课的名字声明为 private .这两个类都执行相同的工作,但只有名称不同的访问说明符.现在,

First class has name declared public and other class has name declared private . Both the classes do the same work but only have access specifiers for name different . Now,

我的问题是?

  • 两个类都支持封装吗?如果这样做,为什么privatepublic更受青睐? (我完成了声明 name 的公开工作,就像我声明了private一样)
  • 哪个类更易于维护?
  • refactoring期间,哪些类程序员会放心?
  • normal 类与 different 类有何不同?
  • 当他们说 Unencapsulated表示不可更改时,在这里它如何不可更改?
  • Do both the classes support encapsulation ? If they do , why are private preferred over public ? (I have done the same work declaring name public as i have done declaring private)
  • Which class is easier to maintain ?
  • With which class programmers will be at ease during refactoring ?
  • How is normal class different , from different class ?
  • When they say Unencapsulated means Unchangeable , how it is unchangeable here ?

推荐答案

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

In "Normal" (there's nothing "normal" about that), this is perfectly legal code:

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

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

Your interface now includes a String value called name. Users will expect to be able to set it using either VarName.name or VarName.setName syntax. Users will expect to be able to retrieve it either with VarName.name or VarName.getName;

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

For example, this is legal in "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 );
}

现在,也许您会想到那又如何?"想象一下,将变量设置为null是否与实际打印(发生错误的地方)相隔30个文件.很难知道谁搞砸了该变量的值.而且,您无能为力,无法阻止用户对其进行破坏.

Now, maybe you'll think "so what?" Imagine if the setting of the variable to null was separated from the actual printing (where the error happens) by 30 files. It will be very hard to know who screwed up the value of that variable. And there's nothing you can do to prevent the user from screwing it up.

现在,如果您已按以下方式实现了setName:

Now, if you had implemented setName as this:

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

然后,该错误立即发生在用户执行错误操作时.用户尝试将值设置为null,该值不允许为null,因此会出错.您有一个调用堆栈,其中显示了错误发生的位置,并且调试起来容易得多.

Then, the error happens immediately upon the user doing something wrong. The user tried to set a value to null that isn't allowed to be null, therefore error. You have a call stack that shows where the error happened, and this is much easier to debug.

当然,这无济于事,因为"Normal"的用户不必必须使用setName.他们可以直接在name处随意戳.

Of course, that doesn't help because the user of "Normal" does not have to use setName. They are free to poke at name directly.

就我而言,从技术上讲它可能是封装,但如果用户可以轻松地颠覆它,则它不是封装.如果没有保护,就没有封装.

While it may technically be encapsulation, as far as I'm concerned, if the user can easily and trivially subvert it, it's not encapsulation. If there's no protection, there's no encapsulation.

当他们说Unencapsulated表示Unchangeable时,在这里如何不可更改?

When they say Unencapsulated means Unchangeable , how it is unchangeable here ?

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

OK, let's say you give me a library containing Normal. I will use it in some way. Maybe I've got Normal instances scattered over 50 files. They all directly set and get the name by the name rather than the accessors. This is perfectly legal because you made it public.

现在,无论出于何种原因,您都决定不想将名称存储在字符串中.也许您需要能够有一个名字和一个姓氏.因此,假设您的库的下一个版本具有以下定义:

Now, you decide, for whatever reason, that you don't want to store the name in a string. Maybe you need to be able to have a first name and a last name. So, let's say the next version of your library has this definition:

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();
    }
}

缺少什么? public String name;该名称不再可用,因为您现在有了名字和姓氏.请注意,这两个访问器方法完全没有改变 .

What's missing? public String name; That's no longer available, because you now have a first and last name. Notice that the two accessor methods did not change at all.

当我升级到库的新版本时,您将破坏了我的所有代码.我不希望仅仅因为您决定更改在类中存储数据的方式而破坏了我的代码.现在,我将不再使用您再做的任何事情,因为您甚至无法保持界面在一个版本与另一个版本之间的一致性.

When I upgrade to the new version of your library, you will have just broken all of my code. I don't like my code to be broken simply because you decided to change how you stored the data in your class. I will now never use anything you make again, because you can't even keep your interface consistent from one version to the next.

如果您做得正确,那一切都不会发生.

And if you had just done things properly, none of that would have happened.

这篇关于这两个类都支持封装和...吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆