Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Java Java Data Structures - Retired Efficiency! Changing Course

Vladislav Kobyakov
Vladislav Kobyakov
9,439 Points

Why am I able to access the list of videos that is private?

My question is why can I access and alter the private member property mVideos from the "Course" class? My original understanding was that since it's been declared as "private" I shouldn't be able to change it unless there is a "setter" method. In this challenge there is only the getVideos() method, but I can still add a video using "course.getVideos().add(1 , video). Will I also be able to remove an element from this list using "coures.getVideos().remove(someIndex)"? I guess I need a bit more explanation on this. Could somebody explain it to me?

Code:

import com.example.model.Course;
import com.example.model.Video;

import java.util.Map;

public class QuickFix {
  public void addForgottenVideo(Course course) {
    List<Video> videoList = course.getVideos(); //Formal step. Can be solved without this.
    // TODO(1):  Create a new video called "The Beginning Bits"
    Video vid = new Video("The Beginning Bits");

    // TODO(2):  Add the newly created video to the course videos as the second video.
    videoList.add(1, vid); //first solution
    course.getVideos().add(1, vid); //second solution
  }

  public void fixVideoTitle(Course course, String oldTitle, String newTitle) {

  }

  public Map<String, Video> videosByTitle(Course course) {
    return null;
  }
}
package com.example.model;

public class Video {
  private String mTitle;

  public Video(String title) {
    mTitle = title;
  }

  public String getTitle() {
    return mTitle;
  }

  public void setTitle(String title) {
    mTitle = title;
  }

}
package com.example.model;

import java.util.List;

public class Course {
  private String mName;
  private List<Video> mVideos; 

  public Course(String name, List<Video> videos) {
    mName = name;
    mVideos = videos;
  }

  public String getName() {
    return mName;
  }

  public List<Video> getVideos() {
    return mVideos;
  }

}

3 Answers

Chris Tvedt
Chris Tvedt
3,795 Points

Hi Vladislav,

You ask a good question. I would imagine that this has to do with the fact that the "List" interface is a public interface with its own default modifier methods.

To make it truly "read-only" you will need to use the "Collections.unModifiableList()" method to return an unmodifiable list.

The "private" modifier just means you can not Directly access the variables. But through other methods you might be able too.

example:

//Setting up a list of videos and a course.
List<Video> videos = new List<>();
videos.add(new Video("This is a new video");
Course newCourse = new Course("course", videos);

You would not be able to do:

newCourse.getVideos().getIndex(0).mTitle = "Trying change title on chosen video";

Because you are not allowed to access the mTitle directly. But you could to it through a setter-method.

That is what is being done in the case of adding to the list. you are accessing the list variables through the "List"-interfaces methods.

This is atleast how i understand it to work and it makes sense in my head.

If someone finds this information to be complete BS, please let me know so i can remove it from the forum.

Please "Up-vote" if this helped you in any way.

Chris.

Vladislav Kobyakov
Vladislav Kobyakov
9,439 Points

Thanks Chris! It makes more sense now, but now I don't really understand what's the privilege of declaring the List<Video> mVideos as private. Since any other class have full access over the mVideos list and any element can be removed using someCourse.getVideos().remove(someIndex) or can be added using someCourse.getVideos().add(someVideo). Does that mean that the getVideos() method breaks the encapsulation of the list itself (or any other container in a different situation) and always has to return Collections.unmodifiableList(mVideos) (or an alternative method for another container type) if intended to be of READ ONLY type?

I've just checked if I declare the List<Video> mVideos from the Course class as public I also can't access a certain title from a certain video from the list as you've mentioned before using someCourse.getVideos().get(someIndex).mTitle. So this brings me back to the question what does the private type modifier do in this situation at all if the getVideos() method lets any class do anything it wants?

Chris Tvedt
Chris Tvedt
3,795 Points

Hi again Vladislav,

If you try running the following code to test your classes

public class Testing    {
    public static void main(String[] args)  {
        //Setting up a list of videos and a course.
        List<Video> videos = new ArrayList<>();
        videos.add(new Video("This is a new video");
        Course newCourse = new Course("course", videos);

        //this does not work with mTitle being private.
        newCourse.getVideos().get(0).mTitle = "Trying change title on chosen video";
        //but if you now change mTitle to be public, you can edit it directly. Thats the purpose of the private modifier.
    }
}

You will now see that if you change the modifier on mTitle to public, you can change the title directly, if its private, you have to go through another method, a setter or through a method in the List-class.

A modifier is just so that you can or can not access a variable/method directly, but you might be able to in-directly, through another method. Like setters and alike.

Did this make it clearer? :-)

Chris

Vladislav Kobyakov
Vladislav Kobyakov
9,439 Points

I actually meant if we change the type modifier of the list mVideos and not the mTitle. It seems to be the case that the ArrayList is always mutable so that's why one should always put additional restrictions on the getter method to make it of "read-only" type... Of course if you change the type modifier for mTitle from private to public, you can access and change it from any other class.

My only concern here was that the list mVideos declared as private doesn't do much as it would be equally accessible from other classes (only the list, not any particular object in the list or that object's member variable) if it was declared as public.

Thanks again for your reply! :)

Chris Tvedt
Chris Tvedt
3,795 Points

I see your point, and yes, if you want full imutability on your list, you will have to use the unModifiableList()-method.

Chris Tvedt
Chris Tvedt
3,795 Points

I think you are mixing the "private"modifier with the "final" keyword. Final makes a variable "un-editable". The "private" just makes it so you cannot access the variable outside the class.

private: can be altered (if not final) but cannot be accessed directly outside its own class.
public: can be altered (if not final) and can be accessed outside its own class.
protected: can be altered (if not final) and can be accesses outside its own class if
           the classes are in the same package. or if it is a subclass of the protected class.

Hope this made things a little clearer. Please up-vote if they did :-)

Chris

Vladislav Kobyakov
Vladislav Kobyakov
9,439 Points

Hello Chris! I've just added the missing code from the challenge and the solution possibilities for the first (out of 3 in total) task. So when I solve it I actually access and modify the private variable of class "Course" from the class "QuickFix". Although I can access and view the list because I'm provided with the public List<Video> getVideos(); method, why am I able to modify it directly from a different class "QuickFix" if it is declared as private?

Chris Tvedt
Chris Tvedt
3,795 Points

Hi Vladislav,

Posten an answer below.