<p>Unless this is an honors programming class, access modifiers may be difficult to understand. I usually start with <em>public</em> vs. <em>private</em> and provide a simple case. For example, it is usually a bad idea to make an instance variable <em>public</em>:</p>

<pre><code>public class Person {
  public int age;   
  public static void main(String[] args) {      
    Person p = new Person();        
    p.age = -99; //bad, but legal       
  }
}
</code></pre>

<p>Instead, make <em>age</em> private and provide public accessor methods:</p>

<pre><code>public class Person {
  private int age;
  public static void main(String[] args) {
    Person p = new Person();
    p.setAge(22); //nice.       
  }

  public void setAge(int age) {
    if (age &lt; 0) {
        System.err.println("error - bad age: " + age);
        age = 0;
    } else
        this.age = age;
  }

  public int getAge() {
    return age;
  } 
}
</code></pre>

CC BY-SA 3.0
2017-06-29T20:31:20.047Z
2017-06-29T20:31:20.047Z
Edwin Torres
<p>I use phone numbers. </p>

<p>You know your cell phone number, and I don't. That makes it a private instance variable. I have no way to get it without you telling it to me. </p>

<p>If it was a public instance variable, instead of you knowing it and me not, it would be tattooed on your forehead. Then, when the creepy guy who wants to ask you out sees you in the hall he can look at your forehead, get your number, and put it in his phone. Congrats, you have your very own stalker. </p>

<p>But you do want to give out your phone number to some people, just as long as you can control who gets it. For that you need to keep the instance variable private, but make a public getter / accessor method like getPhoneNumber(). Now you can do whatever you want to decide if you want to share your phone number with the guy in the hall. Is he creepy? Does he have nice friends? Is he missing teeth? Does he drive a nice car? It's up to you to decide. </p>

<p>And then we backtrack a bit. Tattooed on your forehead is a little over simplified. If it was truly public, anyone could change it. It's more like it was written with washable Crayola marker. Works as a hook for why we need both accessors and modifiers. </p>

<p>I teach mainly AP-A in high school, so those are the only two modifiers I really worry about. We brush on protected when we get a little deeper into inheritance, but by that point they've got public / private down pretty well so it's a short hop. </p>

CC BY-SA 3.0
2017-06-30T07:17:22.573Z
That's a good analogy for how `private` works in Ruby, for example, but in Java, `private`s *are* visible to other objects.
Jörg W Mittag
CC BY-SA 3.0
2017-06-30T11:21:02.280Z
@JörgWMittag urm. not they're not. maybe with Getters and Setters, but not directly.
ItamarG3
CC BY-SA 3.0
2017-06-30T11:22:16.640Z
That's backwards of how I learned and understand it.  Private in Java is not accessible for outside classes.
Ryan Nutt
CC BY-SA 3.0
2017-06-30T11:54:02.630Z
@ItamarG3: Here's a demo: http://ideone.com/nQtdh6#sthash.5nNWwgZY.dpuf
Jörg W Mittag
CC BY-SA 3.0
2017-06-30T11:54:43.290Z
@RyanNutt: Here's a demo: http://ideone.com/nQtdh6#sthash.5nNWwgZY.dpuf
Jörg W Mittag
CC BY-SA 3.0
2017-06-30T12:14:14.033Z
No wonder students find it tough. We're confusing each other :)  My understanding is that private is private to the class, not the object. So your linked code only works because it's a Demo object referencing another Demo object. Look at http://bit.ly/2txr3Kd . The Other class would not work because they're different classes. Fortunately it's rare for early coders to have an object deal with another instance of the same class, so it doesn't come up often. Only place I usually see this oddity is when they're writing compareTo methods.
Ryan Nutt
CC BY-SA 3.0
2017-07-02T13:20:16.690Z
@RyanNutt: I said "in Java, `private`s *are* visible to other objects", and my example demonstrates that. I never said anything about classes. The fact that objects cannot access the private representation of *any* other objects is one of the fundamental differences between objects and abstract data types (where instances of the same ADT *can* inspect each other's private representation). In your example, both objects are instances of the type `Human`, so they *should* be able to read each other's minds, according to the rules of ADTs (e.g. like in Java), but not according to the rules of …
Jörg W Mittag
CC BY-SA 3.0
2017-07-02T13:23:21.087Z
… of objects (e.g. like in Ruby). So, your example is a good example of object-oriented encapsulation as employed in Ruby, but it is not a good example of ADT-oriented encapsulation as employed in Java, since in your example, the objects cannot inspect each other's representation even though they would be able to in Java.
Jörg W Mittag
CC BY-SA 3.0
2017-06-29T20:37:06.587Z
2017-06-29T20:37:06.587Z
Ryan Nutt
<p>I have a distinct memory of my college CS teacher saying "only your friends can touch your <code>private</code>s". The context was C++, and yes there was an accompanying eyebrow waggle.</p>

<p>The meaning was pretty clear &amp; I still remember it after >15 years.</p>

<p>Of course, you may have to tone it down some for high school, but the analogy to one's privates could be useful.</p>

CC BY-SA 3.0
2017-06-29T17:52:55.923Z
2017-06-29T18:42:17.070Z
2017-06-29T18:42:17.070Z
G. Ann - SonarSource Team
<p>This year, I used the example of student grades that seemed to work pretty well (C++):</p>
<ul>
<li>The <code>Student</code> class has a private <code>_grade</code>.</li>
<li>Every student can see every other student's grade.</li>
<li>However, an <code>InsuranceCompany</code> cannot see a student's grade.</li>
<li>For convenience, I want that a <code>Teacher</code> can see and change a <code>Student</code>'s grade. For this reason, the <code>Student</code> defines the <code>Teacher</code> as <code>friend</code>.
<ul>
<li>Of course, the <code>Teacher</code> does not define the <code>Student</code> as <code>friend</code>, so the student cannot see the teacher's grade.</li>
</ul>
</li>
<li>Regarding <code>protected</code>, one can use students of specific programs or levels.</li>
</ul>
<p>The fact that &quot;every student can see each other student's grade&quot; seemed to concern my students and stick quite well, triggering interesting questions (<em>&quot;but how I can do that per object?&quot;</em>).</p>

CC BY-SA 4.0
2023-12-01T17:29:38.747Z
2023-12-01T17:29:38.747Z
MakisH
<p>I think a good way of looking at it is like legislation in the United states. Public would be national law, it impacts everyone in the country. Private is like state or city level law, much smaller scope. Now, all this legislation fits into the protected category because of ex post facto (after the fact in Latin). If you do something legal, and later it becomes illegal, you cannot get charged for the previous action. One can only be charged if the crime is committed after the legislation is passed.</p>

<p>An example:</p>

<ul>
<li><p>(PUBLIC, protected) National level: Pot is completely illegal.</p></li>
<li><p>(PRIVATE, protected) Colorado: Pot is legal for medicinal and recreative use.</p></li>
</ul>

CC BY-SA 3.0
2017-06-29T17:55:58.983Z
I'm not sure I see how the last to sentences are related... Could you expand on that?
ItamarG3
CC BY-SA 3.0
2017-06-29T17:58:52.987Z
Does that help?
itsjtwright
CC BY-SA 3.0
2017-06-29T17:59:53.840Z
But how is it related to oop?
ItamarG3
CC BY-SA 3.0
2017-06-29T18:02:28.277Z
This fits for JS OOP so I don't know if the idea gets across to other languages or not
itsjtwright
CC BY-SA 3.0
2017-06-29T18:08:57.767Z
Oh. ok... Sorry, I'll make my question clearer.
ItamarG3
CC BY-SA 3.0
2017-06-29T18:29:35.847Z
I'm not sure I understand your example, but find it confusing. visibility is about, well, visibility. Laws are about applicability. A private method can have a global effect on a computation, though it can't be referenced globally.
Buffy
CC BY-SA 3.0
2017-06-29T18:38:52.687Z
I understand where you are coming from, the analogy seemed to make sense in my head but I guess it didn't come across, would it be smart just to take it down so no one in the future gets tripped up?
itsjtwright
CC BY-SA 3.0
2017-06-29T17:53:19.343Z
2017-07-15T14:11:32.583Z
2017-07-15T14:11:32.583Z
itsjtwright
<p>Here's an analogy that I've used for several years, and that students seem to understand. It doesn't focus on the rules, but why we have public and private and protected.</p>

<p>"Most of you know that I live down at the beach. If you find yourself riding past my house, and it's hot outside, you might come to my front door, knock and ask if you could have a soda. I don't live in a gated community, so anyone can come to my front door and knock. My front door is public. However, you can't open the front door, walk right in to my kitchen, open the refrigerator door, and help yourself to a soda! My refrigerator door is not public.</p>

<p>My children and grandchildren, however, who live next door, think nothing of walking into the house and getting anything they like out of the refrigerator. In our house, the refrigerator is protected; my family can directly access it, but the general public cannot.</p>

<p>Not everything in our family is protected, though. My kids know that going upstairs, finding my Visa card, and charging a new book at Amazon, isn't permitted. My Visa card, and the contents of my wallet, are private. No one else can access them directly; they have to make a request."</p>

CC BY-SA 3.0
2017-06-29T22:00:52.937Z
I like this analogy very much.  Short, to the point, and mimics the relationships well.  Welcome to [cseducators.se].  I hope we hear more from you in the future!
Ben I.
CC BY-SA 3.0
2017-07-01T08:52:26.460Z
I cannot express enough how useful this is. Thanks. (I will probably accept this soon)
ItamarG3
CC BY-SA 3.0
2017-07-01T15:45:22.280Z
Ultimately it's all about security.  All the examples above has to do with security, and the consequences of such can use the same framework.  If your VISA card is made public, I don't think it takes a lot of imagination to know how bad that really is, so likewise, something like a "bank_balance" variable must definitely be extremely limited.  You cannot just have any random objects modify it outside of specific withdraw() and deposit() methods.  Likewise, a bank teller and an ATM are under the "authorized_entity" environment, and will probably have similar checks for withdraw() and deposit().
Nelson
CC BY-SA 3.0
2017-07-05T00:11:42.757Z
This answer explains (mansplains) *what* the difference is between words that students already know. It does not intuit *why* a particular OOP access level would be used over another. For that, actual programming examples would be required. Would that programming could be taught without programming, and instead by ESL. A popular but wishful fantasy.
Birkensox
CC BY-SA 3.0
2017-07-22T08:10:42.787Z
I like it. It shows how it Java (and all C++ based languages) model access for you, your children, and the public. It also shows how they think you hate your wife and friends. (Ok I forgot `friends`, you can give your friends access to your play-station, by using `interface`s and `friend`s). Eiffel solves this by allowing you simply to declare with classes can access which features of the class
ctrl-alt-delor
CC BY-SA 3.0
2017-06-29T21:21:14.540Z
2017-06-29T21:21:14.540Z
Stephen Gilbert
<p>What my teachers used was the following example, which is pretty simple and most people understood.</p>

<p>Your father orders a pizza. The delivery guy arrives and expects payment. The <code>wallet</code> containing the money belongs to the object <code>father</code></p>

<p>If the wallet is <code>private</code>, then you have to get your father to open it and pay.<br>
If the wallet is <code>protected</code>, you can go and pay the pizza guy.<br>
If the wallet is <code>public</code>, the pizza guy takes it and pays himself</p>

CC BY-SA 3.0
2017-06-30T13:20:43.800Z
Oh. Wow. This is incredible. Welcome to [cseducators.se], I hope we'll be seeing more from you.
ItamarG3
CC BY-SA 3.0
2017-06-30T16:42:34.430Z
One of the most important things I've found for teaching this concept is the idea that you could *want* to restrict access to data or functions.  When we learn coding, "public" is kinda the default way most of us think.  You have to realize there's value in constraining your options before you can understand why you want private.  I think this series of examples using a wallet is an excellent argument for why sometimes you want constraints.
Cort Ammon
CC BY-SA 3.0
2017-06-30T13:18:26.957Z
2017-06-30T13:22:45.727Z
2017-06-30T13:22:45.727Z
shalah allier
<p>Ooh, this is one of my favorite lessons!</p>

<p>I don't introduce <strong>package private</strong> and <strong>protected</strong> in the same lesson as <strong>private</strong> and <strong>public</strong>, because there are 3 principles that I want them to absorb that ultimately motivate the entire system.  My lesson introduces a few more ideas than just permissions (it's really how I get started with Ojects), but the key ideas of encapsulation also lie therein.  The lesson works roughly like this:</p>

<p>Students <em>always</em> default to wanting everything to be <code>public</code>, so I provide a motivating example for why this is a bad idea.  The entire set of steps is rather long, but I will create the setup and give a broad outline of how I proceed from there.</p>

<p>First, up on the projector, I create a point object:</p>

<pre><code>public class Point{
    public double x;
    public double y;
}
</code></pre>

<p>I next create a <code>Geometry</code> class into which I put my <code>public static void main(String[] args)</code>.  I create a point, and show them how to use direct access of public variables: <code>myPoint.x</code> and <code>myPoint.y</code>.  At this point, we have basically created a struct.  When it comes time to print out a few of these points, I create a <code>toString()</code> </p>

<p>Then I create a rectangle class:</p>

<pre><code>public class Rectangle{
    public Point p1;
    public Point p2;
    public double area;

    public Rectangle(
}
</code></pre>

<p>.... right here, I stop, and ask the class how we should create our two points.  This is when I get to the <strong>Motivating Principle #1: it is the responsibility of an object to care for and ensure its own variables</strong>.  Which leads to the question: who should directly set the actual <code>x</code> and <code>y</code> values in each of the two points, the <code>Point</code> object, or the <code>Rectangle</code>?  </p>

<p>Given principle #1 (which I have not yet justified), we opt for the <code>Point</code> object.  So, before we continue with <code>Rectangle</code>, we go back and create a constructor for <code>Point</code>.</p>

<p><em>Before we resume this narrative, the astute reader will notice that the seeds of our destruction are already present in those <code>public</code> variables!</em></p>

<p>My next stop is to finish the <code>Rectangle</code> constructor:</p>

<pre><code>    public Rectangle(double x1, double y1, double x2, double y2){
        p1 = new Point(x1,y1);
        p2 = new Point(x2,y2);
        area = Math.abs(x1-x2) * Math.abs(y1-y2);
    }
</code></pre>

<p>We are almost ready to blow everything up.  I go back to <code>Geometry</code>, create a <code>Rectangle</code>, and then... <em>modify its area!</em></p>

<pre><code>Rectangle r = new Rectangle(0.0,0.0, 1.0,1.0);
System.out.println(r.area);
r.area = Math.PI;
System.out.println(r.area);
</code></pre>

<p>At this point, we get to some obvious questions: </p>

<ol>
<li>Is the area still correct?  And</li>
<li>who is responsible to prevent this sort of malfeasance, anyway?</li>
</ol>

<p>Looking at principle #1, we discover that, though the fault probably likes with <code>Geometry</code>, the real responsibility here lies with <code>Rectangle</code>.  This immediately motivates a series of cascading changes:</p>

<ol>
<li>We make those <code>Point</code>s and the <code>area</code> variables <em>private</em>.</li>
<li>We create a getter for Area.</li>
<li>We create setters for <code>Rectangle</code>s <code>Point</code>s.</li>
<li>We make <code>x</code> and <code>y</code> private in <code>Point</code>, and make getters (but no setters - we just use the constructor here)</li>
</ol>

<p>In the follow-up discussion, we get to <strong>Motivating Principle #2: always provide the least permissions that you can get away with.</strong>  This is what prevents trouble, and helps Objects to guarantee their part of Principle 1.</p>

<p>And finally, I bring them to my <strong>Warning Principle #3: getters and setters are how we grant access to a shielded variable, but if you've created an unmodified (straight/unfiltered) getter and an unmodified setter on the same variable, <em>you are doing it wrong</em>, and you have just made a public variable.</strong></p>

<p>What follows is a series of short Object-design tasks in which I tell them to sketch out, for a series of theoretical private instance variables, appropriate getters and setters.  After each one, we put a student's answer up and I let the kids discuss/critique/defend what is up on the projector.  This gives us a chance to practice our three principles together, and really drives the point home.</p>

<p>I give this lesson high marks, historically, for squelching both <code>public</code> instance variables, and de-facto <code>public</code> created by unfiltered getters and setters on the same variable. Instead, I have found that students generate much more thoughtful object designs.</p>

CC BY-SA 3.0
2017-07-05T00:12:42.963Z
Excellent - there is nothing like a few code snippets to explain a coding concept. Thanks for not giving an ESL lesson on the difference between the words *public, private, etc.*
Birkensox
CC BY-SA 3.0
2017-06-29T21:48:55.360Z
2017-06-29T21:48:55.360Z
Ben I.
<p>I like to draw classes as boxes within each other to describe inheritance (ignoring multiple inheritance). So if <code>Dog</code> and <code>Cat</code> inherit from <code>Animal</code>, I'd have a box labeled <code>Animal</code> containing a <code>Dog</code> box and a <code>Cat</code> box. Inside each box, I'd have 2 sections: Public methods and private methods (and protected methods, which I won't talk about in this answer). Then, using this box drawing, I could indicate that the public methods can get out of the box and be made publicly available, whereas the private methods can't get out of their boxes.</p>

<p><a href="https://i.sstatic.net/UpAW5.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/UpAW5.png" alt="Boxes with labels and arrows to where the methods can be called from"></a></p>

<p>This same idea could also be expressed as a tree structure:</p>

<pre><code>Animal
   change_name (public)
   Dog
      bark (public)
      validate_name (private)
   Cat
      meow (public)
      validate_name (private)
</code></pre>

<p>In that case, public methods can change levels of the tree in either direction, and private methods cannot exit their level (or move to a different class in their level. This part is clearer with boxes).</p>

CC BY-SA 3.0
2017-06-29T18:25:12.023Z
2017-06-29T18:46:06.030Z
2017-06-29T18:46:06.030Z
thesecretmaster
<p>The fact that OO languages support public and private methods and data members is a crucial, important design choices.   </p>

<p>And to get a full, deep understanding of how OO programming works, it is crucial to understand both how they work, and when you'd want to use them, which is another way of explaining why they are in the language.</p>

<p>Many of the analogies in the answers so far can help students learn "how they work", but I wonder whether they break down at some point in explaining "when" to make something public or private, and therefore the "why".</p>

<p>Part of the problem is that we often teach with classes such as this:</p>

<pre><code>public class Student {
  // data members
  private int idNum;
  private String name;

  // getters
  public int getIdNum() { return idNum; }
  public String getName() { return name; }

  // setters
  public void setIdNum(int idNum) { this.idNum = idNum; }
  public void setName(String name) { this.name = name; }
}
</code></pre>

<p>The problem here is that in this class, given that the getters and setters simply provide direct access to reading and writing a primitive value, it is very difficult to argue that they add any value.     To come up with a justification for why name and idNum are private, we have to use arguments that are not very convincing.</p>

<p>It becomes easier to see if you have an abstract data type such as a Dictionary with keys and values that allows insertion and deletion, where it can be implemented (internally) in many different ways: linked lists, hash tables, balanced lookup trees.</p>

<p>You can show that by keeping the details of the internal state private, it is possible to swap out different implementations without needing to change the code that uses the data structure.</p>

<p>But, of course, this is a much more sophisticated example.   It requires more understanding of "where we are headed down the road" then students are typically equipped to understand, or teachers are in a position to explain, if/when students encounter Java as a first programming language.</p>

<p>It is the reason that, from where I sit, Java is an excellent choice of second, or third language, for students that have already done enough programming to appreciate the need for data abstraction and information hiding, because they've tried to write fairly complex programs without those tools.      </p>

<p>It is, however, a poor choice of language to teach first, because it requires students to "accept on faith" many principles of OOP that they have no motivation, reason, or background to understand yet.</p>

<p>I am fully aware that this is an iconoclastic point of view, and "fighting words" for many of the OOP true believers.   I'm fully prepared for the backlash. :-)</p>

CC BY-SA 3.0
2017-06-29T21:36:03.057Z
2017-06-29T21:36:03.057Z
Phill Conrad
<p>Unfortunately this question depends on the language. I'll give a general discussion but focus on Java. </p>

<p>public is, as you say visible from any code in the program (and in the original java concept that meant visible across the globe com.sun.java.Foo.x can be found on your computer - or could be, anyway, in theory). </p>

<p>private can mean (a) visible from anywhere in this class (java) or (b) visible only from this specific object. Object level private is an interesting idea, not often implemented. Usually "private" means class level. </p>

<p>In java, not giving any indication (blank) means visible anywhere in this package and this only means something if all your code is in one package or another. In scala (blank) means public. BTW, it should be in a package. </p>

<p>protected means visible throughout this package AND ALSO visible in subclasses of this class defined outside this package. This is dangerous to use, since it is broader than (blank). It is useful for library code, however. </p>

<p>I know I didn't really give an intuitive answer. For beginners the visibilities should really be public or private. Protected is for libraries primarily and they aren't doing that, I think, and blank is a way to build buggy code since the visibility across their various classes is likely to get them in trouble. So,</p>

<p>Public - like the library<br>
Protected - like the book shelf in your team's workspace<br>
Private - like my bookshelf at home. </p>

<p>Note also that the purpose of visibility, the intention of language designers, is to restrict who (which programmers) can reference code, not which code can reference code. It is intended to facilitate teams working on different parts of a large application and permitting them to work in a namespace (say a class, or a package) in which the work of other programmers doesn't impede progress. Negotiation need to occur only at the boundaries, not over every name everywhere in a (say) 30 million line program. Generally a single programmer (or pair) is, at any given time, responsible for a class. A small team, perhaps, for a package. </p>

CC BY-SA 3.0
2017-06-29T18:19:07.137Z
`private` is **not often implemented*? Urrrm, I don't think so...
ItamarG3
CC BY-SA 3.0
2017-06-29T18:21:17.603Z
Object level private is not often built in to languages, class level private is common; a distinction. It is a language function, not a program choice. Clarified in the answer, I hope.
Buffy
CC BY-SA 3.0
2017-06-29T18:24:49.430Z
They are not complete novices. .. but the bookshelf analogy is very nice.
ItamarG3
CC BY-SA 3.0
2017-06-30T00:39:23.730Z
I emphasized class v object private since students often get it wrong. I once built a language that had object-private (for my compiler course) and learned that it has issues/problems/grief. But note that such a feature protects _code_ from other _code_, rather than _code_ from other _programmers_. One object can't, in such a system, step on the state of another, even in the same class. But one programmer programmed both objects by building their class so is able to prevent inconsistent state. Theoretically. Though bugs happen.
Buffy
CC BY-SA 3.0
2017-06-30T07:13:54.080Z
Just for completeness' sake: in Smalltalk, there are no access levels, however instance variables are always object-private and methods are always public, so the concept of "object-private" is as old as OO itself. In Ruby, instance variables are always object-private, and the `private` access level for methods also means object-private. In Scala, `private` can be accompanied with a scope specifier, and a scope specifier of `this` (i.e. `private[this]`) means object-private. Note that the fact that only an object itself can know about its own representation is a fundamental feature of OO, so …
Jörg W Mittag
CC BY-SA 3.0
2017-06-30T07:15:24.690Z
… if you don't have object-private, you cannot to OO! That's why, e.g. in Java, only instances of interfaces are objects (because interfaces don't specify representation, only behavior, and thus representation is necessarily hidden), instances of classes aren't (because you *cannot* make representation object-private with classes).
Jörg W Mittag
CC BY-SA 3.0
2017-06-30T11:32:25.770Z
Yes, @JörgWMittag, thanks and (blush). I was too focused on Java. I've spent some time this morning wondering why I didn't pick up on the Ruby distinction. Looking back over my old code structure, I realize I just don't write code in which the "need to know" is important. One object directly modifying another is bad practice whether or not the language permits it. If memory serves (not always) my first OOP language was (Apple) Object Pascal in which things were public, so you had to develop a safe style. Thanks for putting me straight. I'm not sure I entirely understand your second note.
Buffy
CC BY-SA 3.0
2017-06-30T12:00:29.137Z
The significance of what is sometimes called *Autognosis* is well explained in [*On Understanding Data Abstraction, Revisited*](http://CS.UTexas.Edu/~wcook/Drafts/2009/essay.pdf) by [William R. Cook](http://WCook.BlogSpot.Com/). The basic idea is that objects are hidden behind a behavioral interface and only an object itself knows about its own representation. That's different from Abstract Data Types, where representation is only hidden from instances of different *types* but accessible to other instances of the same type. In Java classes, there is no way to express this constraint …
Jörg W Mittag
CC BY-SA 3.0
2017-06-30T12:02:15.270Z
… (even `private` is still accessible to other objects of the same class), but interfaces cannot specify representation (no fields, no private methods), so when you only use interfaces as types (no primitives and no classes), then you can guarantee object-oriented encapsulation.
Jörg W Mittag
CC BY-SA 3.0
2017-06-30T12:27:58.777Z
That point is important, but difficult to capture on this site, I fear, since it disfavors discussions like this one. Every type named in a declaration "should" be an interface type, not an implementation type. So, use List foo, not ArrayList foo. A further implication that inheritance "should" not extend the public (informal) interface of a class. If you need to add a new public method in a subclass, extend a formal interface instead and implement that.  Sadly most "simple" examples of inheritance given to novices break this rule completely.
Buffy
CC BY-SA 3.0
2017-06-29T18:16:43.177Z
2017-06-30T13:29:57.017Z
2017-06-30T13:29:57.017Z
Buffy
<p>While teaching OOP in a high school CS major (in java), it is important (and part of the curriculum in any case) to explain &quot;<em>what is the meaning of this <code>public</code> and <code>private</code>?</em>&quot; (A question voiced by many students).</p>
<p>The usual explanation is a technical one:</p>
<ul>
<li>Something <code>public</code> is accessible from anywhere.</li>
<li>Something <code>private</code> is, well, private.</li>
<li><code>protected</code> ??</li>
<li>default access (when no other access modifier is given).</li>
</ul>
<p>As for <code>protected</code>, the students know about inheritance but the explanation of &quot;it can be accessed by things down the inheritance tree&quot; doesn't really get the idea through. Examples only show it so far and only works for a number of students.</p>
<p>So this got me thinking: How can access levels be explained in an intuitive way to high school students?</p>
<p>Note: I'm not only asking about <code>protected</code>, that is my main problem when explaining access levels.</p>
<h2>Clarification</h2>
<p>I am talking about access modifiers for objects and methods, not classes:</p>
<pre><code>public class Example extends JFrame{ //the public in this line is not what I'm asking about.
    private int x; //this is the kind of private asked about
    protected void paintComponents(Graphics g){ //and this is also the kind being asked about.
</code></pre>

CC BY-SA 3.0
2017-06-30T02:34:13.447Z
You need examples of why you would use one access level over another to engage their intuition.
Birkensox
CC BY-SA 3.0
2017-06-30T09:04:44.663Z
@DominicCerisano yes.
ItamarG3
CC BY-SA 3.0
2017-07-04T23:45:12.833Z
By that I mean actual programming examples, rather than merely mansplaining the difference between words which your students already know.
Birkensox
<secondary-education><teaching-analogy><java><object-oriented-paradigm>
Explaining access levels and visibility in OOP
# Explaining access levels and visibility in OOP

(Asked by: username_0 on 2017-06-29)

While teaching OOP in a high school CS major (in java), it is important (and part of the curriculum in any case) to explain "what is the meaning of this public and private?" (A question voiced by many students).
The usual explanation is a technical one:

Something public is accessible from anywhere.
Something private is, well, private.
protected ??
default access (when no other access modifier is given).

As for protected, the students know about inheritance but the explanation of "it can be accessed by things down the inheritance tree" doesn't really get the idea through. Examples only show it so far and only works for a number of students.
So this got me thinking: How can access levels be explained in an intuitive way to high school students?
Note: I'm not only asking about protected, that is my main problem when explaining access levels.
Clarification
I am talking about access modifiers for objects and methods, not classes:
public class Example extends JFrame{ //the public in this line is not what I'm asking about.
    private int x; //this is the kind of private asked about
    protected void paintComponents(Graphics g){ //and this is also the kind being asked about.

**Tags:** secondary-education, teaching-analogy, java, object-oriented-paradigm

> **Comments:**
> **username_1**: You need examples of why you would use one access level over another to engage their intuition.  
> **username_0**: @DominicCerisano yes.  
> **username_1**: By that I mean actual programming examples, rather than merely mansplaining the difference between words which your students already know.  

---

## 11 answers

### Answer by username_9 on 2017-06-29. Score: 32 | Accepted answer

Here's an analogy that I've used for several years, and that students seem to understand. It doesn't focus on the rules, but why we have public and private and protected.

"Most of you know that I live down at the beach. If you find yourself riding past my house, and it's hot outside, you might come to my front door, knock and ask if you could have a soda. I don't live in a gated community, so anyone can come to my front door and knock. My front door is public. However, you can't open the front door, walk right in to my kitchen, open the refrigerator door, and help yourself to a soda! My refrigerator door is not public.

My children and grandchildren, however, who live next door, think nothing of walking into the house and getting anything they like out of the refrigerator. In our house, the refrigerator is protected; my family can directly access it, but the general public cannot.

Not everything in our family is protected, though. My kids know that going upstairs, finding my Visa card, and charging a new book at Amazon, isn't permitted. My Visa card, and the contents of my wallet, are private. No one else can access them directly; they have to make a request."

> **Comments:**
> **username_10**: I like this analogy very much.  Short, to the point, and mimics the relationships well.  Welcome to [cseducators.se].  I hope we hear more from you in the future!  
> **username_0**: I cannot express enough how useful this is. Thanks. (I will probably accept this soon)  
> **username_11**: Ultimately it's all about security.  All the examples above has to do with security, and the consequences of such can use the same framework.  If your VISA card is made public, I don't think it takes a lot of imagination to know how bad that really is, so likewise, something like a "bank_balance" variable must definitely be extremely limited.  You cannot just have any random objects modify it outside of specific withdraw() and deposit() methods.  Likewise, a bank teller and an ATM are under the "authorized_entity" environment, and will probably have similar checks for withdraw() and deposit().  
> **username_1**: This answer explains (mansplains) *what* the difference is between words that students already know. It does not intuit *why* a particular OOP access level would be used over another. For that, actual programming examples would be required. Would that programming could be taught without programming, and instead by ESL. A popular but wishful fantasy.  
> **username_12**: I like it. It shows how it Java (and all C++ based languages) model access for you, your children, and the public. It also shows how they think you hate your wife and friends. (Ok I forgot `friends`, you can give your friends access to your play-station, by using `interface`s and `friend`s). Eiffel solves this by allowing you simply to declare with classes can access which features of the class  

---

### Answer by username_13 on 2017-06-30. Score: 13

What my teachers used was the following example, which is pretty simple and most people understood.

Your father orders a pizza. The delivery guy arrives and expects payment. The `wallet` containing the money belongs to the object `father`

If the wallet is `private`, then you have to get your father to open it and pay.  
If the wallet is `protected`, you can go and pay the pizza guy.  
If the wallet is `public`, the pizza guy takes it and pays himself

> **Comments:**
> **username_0**: Oh. Wow. This is incredible. Welcome to [cseducators.se], I hope we'll be seeing more from you.  
> **username_14**: One of the most important things I've found for teaching this concept is the idea that you could *want* to restrict access to data or functions.  When we learn coding, "public" is kinda the default way most of us think.  You have to realize there's value in constraining your options before you can understand why you want private.  I think this series of examples using a wallet is an excellent argument for why sometimes you want constraints.  

---

### Answer by username_10 on 2017-06-29. Score: 12

Ooh, this is one of my favorite lessons!
I don't introduce package private and protected in the same lesson as private and public, because there are 3 principles that I want them to absorb that ultimately motivate the entire system.  My lesson introduces a few more ideas than just permissions (it's really how I get started with Ojects), but the key ideas of encapsulation also lie therein.  The lesson works roughly like this:
Students always default to wanting everything to be public, so I provide a motivating example for why this is a bad idea.  The entire set of steps is rather long, but I will create the setup and give a broad outline of how I proceed from there.
First, up on the projector, I create a point object:
public class Point{
    public double x;
    public double y;
}

I next create a Geometry class into which I put my public static void main(String[] args).  I create a point, and show them how to use direct access of public variables: myPoint.x and myPoint.y.  At this point, we have basically created a struct.  When it comes time to print out a few of these points, I create a toString() 
Then I create a rectangle class:
public class Rectangle{
    public Point p1;
    public Point p2;
    public double area;

    public Rectangle(
}

.... right here, I stop, and ask the class how we should create our two points.  This is when I get to the Motivating Principle #1: it is the responsibility of an object to care for and ensure its own variables.  Which leads to the question: who should directly set the actual x and y values in each of the two points, the Point object, or the Rectangle?  
Given principle #1 (which I have not yet justified), we opt for the Point object.  So, before we continue with Rectangle, we go back and create a constructor for Point.
Before we resume this narrative, the astute reader will notice that the seeds of our destruction are already present in those public variables!
My next stop is to finish the Rectangle constructor:
    public Rectangle(double x1, double y1, double x2, double y2){
        p1 = new Point(x1,y1);
        p2 = new Point(x2,y2);
        area = Math.abs(x1-x2) * Math.abs(y1-y2);
    }

We are almost ready to blow everything up.  I go back to Geometry, create a Rectangle, and then... modify its area!
Rectangle r = new Rectangle(0.0,0.0, 1.0,1.0);
System.out.println(r.area);
r.area = Math.PI;
System.out.println(r.area);

At this point, we get to some obvious questions: 

Is the area still correct?  And
who is responsible to prevent this sort of malfeasance, anyway?

Looking at principle #1, we discover that, though the fault probably likes with Geometry, the real responsibility here lies with Rectangle.  This immediately motivates a series of cascading changes:

We make those Points and the area variables private.
We create a getter for Area.
We create setters for Rectangles Points.
We make x and y private in Point, and make getters (but no setters - we just use the constructor here)

In the follow-up discussion, we get to Motivating Principle #2: always provide the least permissions that you can get away with.  This is what prevents trouble, and helps Objects to guarantee their part of Principle 1.
And finally, I bring them to my Warning Principle #3: getters and setters are how we grant access to a shielded variable, but if you've created an unmodified (straight/unfiltered) getter and an unmodified setter on the same variable, you are doing it wrong, and you have just made a public variable.
What follows is a series of short Object-design tasks in which I tell them to sketch out, for a series of theoretical private instance variables, appropriate getters and setters.  After each one, we put a student's answer up and I let the kids discuss/critique/defend what is up on the projector.  This gives us a chance to practice our three principles together, and really drives the point home.
I give this lesson high marks, historically, for squelching both public instance variables, and de-facto public created by unfiltered getters and setters on the same variable. Instead, I have found that students generate much more thoughtful object designs.

> **Comments:**
> **username_1**: Excellent - there is nothing like a few code snippets to explain a coding concept. Thanks for not giving an ESL lesson on the difference between the words *public, private, etc.*  

---

### Answer by username_15 on 2017-06-29. Score: 2

I like to draw classes as boxes within each other to describe inheritance (ignoring multiple inheritance). So if Dog and Cat inherit from Animal, I'd have a box labeled Animal containing a Dog box and a Cat box. Inside each box, I'd have 2 sections: Public methods and private methods (and protected methods, which I won't talk about in this answer). Then, using this box drawing, I could indicate that the public methods can get out of the box and be made publicly available, whereas the private methods can't get out of their boxes.

This same idea could also be expressed as a tree structure:
Animal
   change_name (public)
   Dog
      bark (public)
      validate_name (private)
   Cat
      meow (public)
      validate_name (private)

In that case, public methods can change levels of the tree in either direction, and private methods cannot exit their level (or move to a different class in their level. This part is clearer with boxes).


---

### Answer by username_16 on 2017-06-29. Score: 2

The fact that OO languages support public and private methods and data members is a crucial, important design choices.   
And to get a full, deep understanding of how OO programming works, it is crucial to understand both how they work, and when you'd want to use them, which is another way of explaining why they are in the language.
Many of the analogies in the answers so far can help students learn "how they work", but I wonder whether they break down at some point in explaining "when" to make something public or private, and therefore the "why".
Part of the problem is that we often teach with classes such as this:
public class Student {
  // data members
  private int idNum;
  private String name;

  // getters
  public int getIdNum() { return idNum; }
  public String getName() { return name; }

  // setters
  public void setIdNum(int idNum) { this.idNum = idNum; }
  public void setName(String name) { this.name = name; }
}

The problem here is that in this class, given that the getters and setters simply provide direct access to reading and writing a primitive value, it is very difficult to argue that they add any value.     To come up with a justification for why name and idNum are private, we have to use arguments that are not very convincing.
It becomes easier to see if you have an abstract data type such as a Dictionary with keys and values that allows insertion and deletion, where it can be implemented (internally) in many different ways: linked lists, hash tables, balanced lookup trees.
You can show that by keeping the details of the internal state private, it is possible to swap out different implementations without needing to change the code that uses the data structure.
But, of course, this is a much more sophisticated example.   It requires more understanding of "where we are headed down the road" then students are typically equipped to understand, or teachers are in a position to explain, if/when students encounter Java as a first programming language.
It is the reason that, from where I sit, Java is an excellent choice of second, or third language, for students that have already done enough programming to appreciate the need for data abstraction and information hiding, because they've tried to write fairly complex programs without those tools.      
It is, however, a poor choice of language to teach first, because it requires students to "accept on faith" many principles of OOP that they have no motivation, reason, or background to understand yet.
I am fully aware that this is an iconoclastic point of view, and "fighting words" for many of the OOP true believers.   I'm fully prepared for the backlash. :-)


---

### Answer by username_8 on 2017-06-29. Score: 2

Unfortunately this question depends on the language. I'll give a general discussion but focus on Java.

public is, as you say visible from any code in the program (and in the original java concept that meant visible across the globe com.sun.java.Foo.x can be found on your computer - or could be, anyway, in theory).

private can mean (a) visible from anywhere in this class (java) or (b) visible only from this specific object. Object level private is an interesting idea, not often implemented. Usually "private" means class level.

In java, not giving any indication (blank) means visible anywhere in this package and this only means something if all your code is in one package or another. In scala (blank) means public. BTW, it should be in a package.

protected means visible throughout this package AND ALSO visible in subclasses of this class defined outside this package. This is dangerous to use, since it is broader than (blank). It is useful for library code, however.

I know I didn't really give an intuitive answer. For beginners the visibilities should really be public or private. Protected is for libraries primarily and they aren't doing that, I think, and blank is a way to build buggy code since the visibility across their various classes is likely to get them in trouble. So,

Public - like the library  
Protected - like the book shelf in your team's workspace  
Private - like my bookshelf at home.

Note also that the purpose of visibility, the intention of language designers, is to restrict who (which programmers) can reference code, not which code can reference code. It is intended to facilitate teams working on different parts of a large application and permitting them to work in a namespace (say a class, or a package) in which the work of other programmers doesn't impede progress. Negotiation need to occur only at the boundaries, not over every name everywhere in a (say) 30 million line program. Generally a single programmer (or pair) is, at any given time, responsible for a class. A small team, perhaps, for a package.

> **Comments:**
> **username_0**: `private` is **not often implemented*? Urrrm, I don't think so...  
> **username_8**: Object level private is not often built in to languages, class level private is common; a distinction. It is a language function, not a program choice. Clarified in the answer, I hope.  
> **username_0**: They are not complete novices. .. but the bookshelf analogy is very nice.  
> **username_8**: I emphasized class v object private since students often get it wrong. I once built a language that had object-private (for my compiler course) and learned that it has issues/problems/grief. But note that such a feature protects _code_ from other _code_, rather than _code_ from other _programmers_. One object can't, in such a system, step on the state of another, even in the same class. But one programmer programmed both objects by building their class so is able to prevent inconsistent state. Theoretically. Though bugs happen.  
> **username_4**: Just for completeness' sake: in Smalltalk, there are no access levels, however instance variables are always object-private and methods are always public, so the concept of "object-private" is as old as OO itself. In Ruby, instance variables are always object-private, and the `private` access level for methods also means object-private. In Scala, `private` can be accompanied with a scope specifier, and a scope specifier of `this` (i.e. `private[this]`) means object-private. Note that the fact that only an object itself can know about its own representation is a fundamental feature of OO, so …  
> **username_4**: … if you don't have object-private, you cannot to OO! That's why, e.g. in Java, only instances of interfaces are objects (because interfaces don't specify representation, only behavior, and thus representation is necessarily hidden), instances of classes aren't (because you *cannot* make representation object-private with classes).  
> **username_8**: Yes, @JörgWMittag, thanks and (blush). I was too focused on Java. I've spent some time this morning wondering why I didn't pick up on the Ruby distinction. Looking back over my old code structure, I realize I just don't write code in which the "need to know" is important. One object directly modifying another is bad practice whether or not the language permits it. If memory serves (not always) my first OOP language was (Apple) Object Pascal in which things were public, so you had to develop a safe style. Thanks for putting me straight. I'm not sure I entirely understand your second note.  
> **username_4**: The significance of what is sometimes called *Autognosis* is well explained in [*On Understanding Data Abstraction, Revisited*](http://CS.UTexas.Edu/~wcook/Drafts/2009/essay.pdf) by [William R. Cook](http://WCook.BlogSpot.Com/). The basic idea is that objects are hidden behind a behavioral interface and only an object itself knows about its own representation. That's different from Abstract Data Types, where representation is only hidden from instances of different *types* but accessible to other instances of the same type. In Java classes, there is no way to express this constraint …  
> **username_4**: … (even `private` is still accessible to other objects of the same class), but interfaces cannot specify representation (no fields, no private methods), so when you only use interfaces as types (no primitives and no classes), then you can guarantee object-oriented encapsulation.  
> **username_8**: That point is important, but difficult to capture on this site, I fear, since it disfavors discussions like this one. Every type named in a declaration "should" be an interface type, not an implementation type. So, use List foo, not ArrayList foo. A further implication that inheritance "should" not extend the public (informal) interface of a class. If you need to add a new public method in a subclass, extend a formal interface instead and implement that.  Sadly most "simple" examples of inheritance given to novices break this rule completely.  

---

### Answer by username_2 on 2017-06-29. Score: 1

Unless this is an honors programming class, access modifiers may be difficult to understand. I usually start with public vs. private and provide a simple case. For example, it is usually a bad idea to make an instance variable public:
public class Person {
  public int age;   
  public static void main(String[] args) {      
    Person p = new Person();        
    p.age = -99; //bad, but legal       
  }
}

Instead, make age private and provide public accessor methods:
public class Person {
  private int age;
  public static void main(String[] args) {
    Person p = new Person();
    p.setAge(22); //nice.       
  }

  public void setAge(int age) {
    if (age < 0) {
        System.err.println("error - bad age: " + age);
        age = 0;
    } else
        this.age = age;
  }

  public int getAge() {
    return age;
  } 
}


---

### Answer by username_3 on 2017-06-29. Score: 1

I use phone numbers.

You know your cell phone number, and I don't. That makes it a private instance variable. I have no way to get it without you telling it to me.

If it was a public instance variable, instead of you knowing it and me not, it would be tattooed on your forehead. Then, when the creepy guy who wants to ask you out sees you in the hall he can look at your forehead, get your number, and put it in his phone. Congrats, you have your very own stalker.

But you do want to give out your phone number to some people, just as long as you can control who gets it. For that you need to keep the instance variable private, but make a public getter / accessor method like getPhoneNumber(). Now you can do whatever you want to decide if you want to share your phone number with the guy in the hall. Is he creepy? Does he have nice friends? Is he missing teeth? Does he drive a nice car? It's up to you to decide.

And then we backtrack a bit. Tattooed on your forehead is a little over simplified. If it was truly public, anyone could change it. It's more like it was written with washable Crayola marker. Works as a hook for why we need both accessors and modifiers.

I teach mainly AP-A in high school, so those are the only two modifiers I really worry about. We brush on protected when we get a little deeper into inheritance, but by that point they've got public / private down pretty well so it's a short hop.

> **Comments:**
> **username_4**: That's a good analogy for how `private` works in Ruby, for example, but in Java, `private`s *are* visible to other objects.  
> **username_0**: @JörgWMittag urm. not they're not. maybe with Getters and Setters, but not directly.  
> **username_3**: That's backwards of how I learned and understand it.  Private in Java is not accessible for outside classes.  
> **username_4**: @username_0: Here's a demo: http://ideone.com/nQtdh6#sthash.5nNWwgZY.dpuf  
> **username_4**: @RyanNutt: Here's a demo: http://ideone.com/nQtdh6#sthash.5nNWwgZY.dpuf  
> **username_3**: No wonder students find it tough. We're confusing each other :)  My understanding is that private is private to the class, not the object. So your linked code only works because it's a Demo object referencing another Demo object. Look at http://bit.ly/2txr3Kd . The Other class would not work because they're different classes. Fortunately it's rare for early coders to have an object deal with another instance of the same class, so it doesn't come up often. Only place I usually see this oddity is when they're writing compareTo methods.  
> **username_4**: @RyanNutt: I said "in Java, `private`s *are* visible to other objects", and my example demonstrates that. I never said anything about classes. The fact that objects cannot access the private representation of *any* other objects is one of the fundamental differences between objects and abstract data types (where instances of the same ADT *can* inspect each other's private representation). In your example, both objects are instances of the type `Human`, so they *should* be able to read each other's minds, according to the rules of ADTs (e.g. like in Java), but not according to the rules of …  
> **username_4**: … of objects (e.g. like in Ruby). So, your example is a good example of object-oriented encapsulation as employed in Ruby, but it is not a good example of ADT-oriented encapsulation as employed in Java, since in your example, the objects cannot inspect each other's representation even though they would be able to in Java.  

---

### Answer by username_5 on 2017-06-29. Score: 1

I have a distinct memory of my college CS teacher saying "only your friends can touch your `private`s". The context was C++, and yes there was an accompanying eyebrow waggle.

The meaning was pretty clear & I still remember it after >15 years.

Of course, you may have to tone it down some for high school, but the analogy to one's privates could be useful.


---

### Answer by username_6 on 2023-12-01. Score: 1

This year, I used the example of student grades that seemed to work pretty well (C++):

* The `Student` class has a private `_grade`.
* Every student can see every other student's grade.
* However, an `InsuranceCompany` cannot see a student's grade.
* For convenience, I want that a `Teacher` can see and change a `Student`'s grade. For this reason, the `Student` defines the `Teacher` as `friend`.
  + Of course, the `Teacher` does not define the `Student` as `friend`, so the student cannot see the teacher's grade.
* Regarding `protected`, one can use students of specific programs or levels.

The fact that "every student can see each other student's grade" seemed to concern my students and stick quite well, triggering interesting questions (*"but how I can do that per object?"*).


---

### Answer by username_7 on 2017-06-29. Score: -3

I think a good way of looking at it is like legislation in the United states. Public would be national law, it impacts everyone in the country. Private is like state or city level law, much smaller scope. Now, all this legislation fits into the protected category because of ex post facto (after the fact in Latin). If you do something legal, and later it becomes illegal, you cannot get charged for the previous action. One can only be charged if the crime is committed after the legislation is passed.

An example:

* (PUBLIC, protected) National level: Pot is completely illegal.
* (PRIVATE, protected) Colorado: Pot is legal for medicinal and recreative use.

> **Comments:**
> **username_0**: I'm not sure I see how the last to sentences are related... Could you expand on that?  
> **username_7**: Does that help?  
> **username_0**: But how is it related to oop?  
> **username_7**: This fits for JS OOP so I don't know if the idea gets across to other languages or not  
> **username_0**: Oh. ok... Sorry, I'll make my question clearer.  
> **username_8**: I'm not sure I understand your example, but find it confusing. visibility is about, well, visibility. Laws are about applicability. A private method can have a global effect on a computation, though it can't be referenced globally.  
> **username_7**: I understand where you are coming from, the analogy seemed to make sense in my head but I guess it didn't come across, would it be smart just to take it down so no one in the future gets tripped up?  

---

