返回对象时在Java中封装

时间:2014-07-21 12:19:20

标签: encapsulation

请考虑以下示例:

 public class sample{
     private Map myMap;

     public Map getMap(){

     return myMap;
     }
    }

在上面的例子中,我们将地图返回给其他一些调用类。所以我的问题是我们怎么说这个类封装/保护它的数据。将返回的Map将可供其他类修改。

谢谢, 拉詹

2 个答案:

答案 0 :(得分:0)

也许您可以使用Java Collection API中的unmodifiable map

public class sample{
    private Map myMap;

    public Map getMap(){
        return Collections.unmodifiableMap(myMap));
    }
}

答案 1 :(得分:0)

考虑此类,它有2个属性(名称年龄)。

package app;

/**
 *
 * @author salathielgenese
 */
public final class Person
{

    public Person()
    {
        setAge(age);
        setName(name);
    }

    public Person(String name, long age)
    {
        setName(name);
        setAge(age);
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public long getAge()
    {
        return age;
    }

    public void setAge(long age)
    {
        this.age = age;
    }

    private String name;
    private long age;
}

现在想象一下(假设调用类)将年龄设置为 -19 。这将导致您的不一致。

因此,当您保护自己的数据时,您可以控制这些数据。 您可以决定,如果给定年龄低于0 ,则年龄将设置为 0 。代码可能会变成......

    public void setAge(long age)
    {
        this.age = age;
        if (age < 0)
        {
            this.age = 0;
        }
    }

您可以对名称属性执行相同操作,以防止将其设置为 null

    public void setName(String name)
    {
        this.name = name;
        if (name == null || name == "")
        {
            this.name = "NO NAME";
        }
    }

我们会说封装有助于保护数据。

··············································· ···········································

现在让我们想象一个名为 Carpenter 的课程。当你需要一张桌子时,你只需要问他。因此, Carpenter 类应该提供方法,它会描述您需要的表格,并返回构建表格。假设该方法名为 buildTable ,则此方法将使用公共访问进行声明,因为从另一个类调用它是有用的。

当你要求 Carpenter 建立你的时,他需要检查一些材料以及看到等等到目前为止。 我们(调用类)不关心此内部机制,此进程中涉及的所有方法以及属性将声明为< strong>私有 访问。即阻止外部类修改,即封装我们的字段和方法以获得更好的保护

封装字段让我们可以控制对数据的访问。

回到您的代码,让公众可以访问 getMap()并不会阻止调用类修改其内容。

现在看看示例

<强> Person.java

package app;

/**
 *
 * @author salathielgenese
 */
public final class Person
{

    public Person()
    {
        setAge(age);
        setName(name);
    }

    public Person(String name, long age)
    {
        setName(name);
        setAge(age);
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
        if (name == null || name == "")
        {
            this.name = "NO NAME";
        }
    }

    public long getAge()
    {
        return age;
    }

    public void setAge(long age)
    {
        this.age = age;
        if (age < 0)
        {
            this.age = 0;
        }
    }

    @Override
    public String toString()
    {
        return "Person{" + "name=" + name + ", age=" + age + '}';
    }

    private String name;
    private long age;
}

<强> Example.java

package app;

/**
 *
 * @author salathielgenese
 */
public class Example
{

    public Example()
    {
    }

    public Example(Person person)
    {
        this.person = person;
    }

    public Person getPerson()
    {
        return person;
    }

    public void setPerson(Person person)
    {
        this.person = person;
    }

    private Person person;
}

**主类(Loader.java)

package app;

/**
 *
 * @author salathielgenese
 */
public class Loader
{

    /**
 * @param args the command line arguments
 */
    public static void main(String[] args)
    {
        // Instantiate an Example with a new created Person
        Example example = new Example(new Person("Rajan", 19));
        // Retrive person in example and print its description (printing result of implicit call to person.toString() )
        Person person = example.getPerson();
        System.out.println(person);
        // Assigning a new reference to the variable **person** and print its description
        person = new Person("Salathiel", 20);
        System.out.println(person);
        // Print description of Person containning in Example instance
        System.out.println(example.getPerson());
    }

}

如果您关闭此代码,您就会明白可以更改地图的属性,但不能更改对它的引用。