Page 1 of 1

About Question enthuware.ocajp.i.v7.2.844 :

Posted: Fri Oct 05, 2012 7:40 am
by ETS User
How to solve this type of questions? What are the parameters or rules that tells us how to improve the encapsulation. I know:
1. All the instance variables should be private and getter and setters should be provided to access them.
What are the other rules so that I can solve such questions?
I also could not understand why option 4 is correct?

Re: About Question enthuware.ocajp.i.v7.2.844 :

Posted: Fri Oct 05, 2012 1:14 pm
by admin
Encapsulation ensures that the users of an object aren't able to modify an object without going through appropriatly published accessors. The idea is to make sure that an object "knows" who is doing what to it. So for example, if you have a public data member, any one can just change it and the object wouldn't even notice. But if the modification code is exposed through a setter method, the object knows when its member is changed and can take appropriate actions if necessary.

Option 4 is correct because if you return a reference to the ArrayList itself, the receiving object can be modify the contents of the ArrayList without the owner object knowing about the modification. Therefore, to properly encapsulate this member, a copy of the ArrayList should be returned.

So, the rule that you stated is correct but it is just a guideline for achieving what we are actually trying to achieve by encapsulation.

HTH,
Paul.

Re: About Question enthuware.ocajp.i.v7.2.844 :

Posted: Wed Jul 17, 2013 1:20 pm
by lucas91
I think I got why its better to return a new copy of the ArrayList in terms of encapsulation, but I can't see what could happen if I just returned the reference to the ArrayList in this case because the list is only used to calculate the student average and once the class is instantiated the average is already set, so if one try to add a new value to the score List, he must know he must recalculate the average. Even receiving a copy of the List if he wants a updated average he should use a public recalculate method, the difference being the original score list is untouched.
So please explain to me why would be wrong in this case to change the original score List instead of creating a new copy?
Also, does this means every time I have a instance member of type List my methods should return a copy instead of the List or is this scenario a special case?

Re: About Question enthuware.ocajp.i.v7.2.844 :

Posted: Wed Jul 17, 2013 1:52 pm
by admin
The issue is not just with computing average score. The issue is with the loss of integrity of the scores of a Student object. If you return the original ArrayList the receiver can do anything with it. It can even insert random integers into it. It can inadvertantly pass this reference on to someone else who may not even be aware that it is a list of scores of a student.

So it is never a good idea to expose internal objects for modification outside of that class.

HTH,
Paul.

Re: About Question enthuware.ocajp.i.v7.2.844 :

Posted: Mon Apr 17, 2017 8:04 am
by java_learner
What is the line of thought to rule out the answer "Make getScores() protected"? I mean, I see that it doesn't make much sense to do it. But if I am pedantic (what this test usually is) then I'd say that making getScores() protected actually will provide _more_ encapsulation - don't ask me why, but maybe you don't want classes which are not inheriting or in your package to be able to call this method...

anyway, I just would have liked to see in the answer to this question _why_ making getScores protected should not be considered as improving encapsulation. Sometimes you have these questions where methods are just called m1() or aaa(). There, where we can't see intent of the method in the name, how can making a member from public to protected not be interpreted as improving encapsulation?

sorry for being so pedantic about this. I'm just trying to understand the rationale behind it.

Re: About Question enthuware.ocajp.i.v7.2.844 :

Posted: Mon Apr 17, 2017 9:47 am
by admin
Good question, java_learner! Encapsulation is about the state of an object. The state of an object is determined by the values that its instance members hold. Making getScores protected or public has no impact on the state of the object and therefore it does not affect the extent of encapsulation in this class.

HTH,
Paul.

Re: About Question enthuware.ocajp.i.v7.2.844 :

Posted: Mon Apr 17, 2017 11:59 am
by java_learner
Thank you very much for your answer - this indeed makes sense!

To take this one step further:
what about if the method in question was a setter instead, i.e. a method which can change the state of the object? would you then consider the "protected" keyword to improve encapsulation?

Re: About Question enthuware.ocajp.i.v7.2.844 :

Posted: Mon Apr 17, 2017 9:59 pm
by admin
Another good question. You need to understand that it is the "implementation detail" of a feature or property of a class that you are trying to protect or want to prevent from exposure.

When you have a setX (and/or getX) method in a class, that means the class has a "property" named x. It may or may not necessarily have an instance field named x. Having an instance field x is just one way of supporting that property. It is implementation detail of how that class is able to support the property named x. Other classes have no business getting under the hood of a class and finding that out. If any other class is able to find out how a property x is being implemented by the class, the class is not properly encapsulated.

In simple terms, having Setters/getters is the right way for a class expose its properties as opposed to exposing its instance fields to other classes.

So no, changing the access rights of a setter does not affect encapsulation because you are not exposing the implementation detail either way.

HTH,
Paul.

Re: About Question enthuware.ocajp.i.v7.2.844 :

Posted: Mon Apr 24, 2017 3:11 pm
by java_learner
Thank you very much for the sound answer!

Re: About Question enthuware.ocajp.i.v7.2.844 :

Posted: Fri Sep 22, 2017 1:02 pm
by Sergey
It is possible that i am stupid but... i dont understan how
Option 4 is correct because if you return a reference to the ArrayList itself, the receiving object can be modify the contents of the ArrayList
I try to "modify the contents of the ArrayList" and i get java.util.ConcurrentModificationException

I just dont understand, how can i modify the contents of the ArrayList? I want to understand it.
Here is my code and it does not work.

Code: Select all

public class Test  {
    ArrayList<Integer> scores = new ArrayList<>();
    public ArrayList<Integer> getScores()
    { return scores;  }

    public void setScores(int a)
    { scores.add(a);    }

    public static void main(String[] args)
    {
        Test asd = new Test();
        asd.setScores(5);
        asd.setScores(5);    
        ArrayList<Integer> result = asd.getScores();
        for (Integer element : result)
        {
            System.out.println(element);
            asd.setScores(6); =========== Exception
        }

    }

}

Re: About Question enthuware.ocajp.i.v7.2.844 :

Posted: Fri Sep 22, 2017 8:58 pm
by admin
You are getting an exception because you are trying to modify the list while you are iterating through it. Remove the for loop:

ArrayList<Integer> result = asd.getScores();
result.add(100);

Re: About Question enthuware.ocajp.i.v7.2.844 :

Posted: Tue Dec 12, 2017 5:03 am
by Rinkesh
Hi there,I want to ask how is Make computeAverage() public not right?Methods should normally be public in order to be accessible anywhere,right? Or In this case,It doesn't even matter since there is only one Class?

Re: About Question enthuware.ocajp.i.v7.2.844 :

Posted: Tue Dec 12, 2017 9:33 am
by admin
Methods need to be public only if you want them to be accessed from non-subclass classes outside the package. A default access method can be accessed from any class within the same package. So it is not always necessary for a method to be public.

Re: About Question enthuware.ocajp.i.v7.2.844 :

Posted: Tue Feb 06, 2018 2:49 am
by igor.simecki
I wouldn't completely agree with the correct answer 4.
There's a big :What if I want to change this student's scores and recompute the average? The integrity of the Student object is fine as long as I can't directly access the list reference and possibly null it causing computeAverage() to fail completely.
Also, what's the point of this whole code if scores isn't set or filled anywhere? The 4th answer is really stretching it.
If 4 were irrefutably the most correct answer the Student object would be one big bunker with no doors. I don't see the use in that.

Re: About Question enthuware.ocajp.i.v7.2.844 :

Posted: Tue Feb 06, 2018 3:13 am
by admin
Your argument is correct , but the question only asks you to improve the encapsulation aspect of the class, not the "usefulness" of the class. One could certainly make the class useful by applying other changes that are not relevant to this question but while letting the class be well encapsulated.

Re: About Question enthuware.ocajp.i.v7.2.844 :

Posted: Wed Mar 11, 2020 7:05 am
by evaevaeva
But what I still don't understand is why we should not 'Make computeAverage() public', since the goal of encapsulation is 1. Declare the variables of a class as private and 2. Provide public setter and getter methods to modify and view the variables values. And is computeAverage() not a 'setter'?

Re: About Question enthuware.ocajp.i.v7.2.844 :

Posted: Wed Mar 11, 2020 7:13 am
by admin
No, computeAverage is neither a getter nor a setter! It does not start with a get(or is) or set. "computeAverage" is not a property of this class. "average" is and there is a getter for that already.