-2

So a 'fundamental' OOP principle is being able to control the access to various methods and fields from other parts of the program by making them public or private. The reason is so that you cannot access an internal item or something.

But why would you not want to be able to access an internal property? And if they absolutely should not be accessed, why can programmers not just know not to do it, instead of needing to explicitly define these in the language?

7
  • 1
    I want to point out here that I don't appreciate you actively trying to edit my answer and redact the parts which you don't like. You have tools to up/downvote if you (dis)agree with an answer, without needing to resort to defacing it.
    – Flater
    Commented Apr 16 at 1:30
  • actually help programmers => they do in the same way an autopilot helps someone with a Cessna 172 rating fly a modern jetliner, or a formula one car helps one commute to work in Monte Carlo. i.e. If you don't know what you are doing you're going to make a mess that will be hard to clean up. And so it is with OO principles (real or imagined) and language features. –
    – radarbob
    Commented Apr 16 at 2:03
  • 3
    Duplicate of Why do we need private variables?
    – Basilevs
    Commented Apr 16 at 5:44
  • 1
    Does this answer your question? Why do we need private variables? Commented Apr 16 at 6:59
  • 1
    @GregBurghardt It's a good point but even in Python, it's not entirely convention. For example, names with leading underscores are excluded from wildcard imports.
    – JimmyJames
    Commented Apr 16 at 14:55

4 Answers 4

5

This sounds like a rant trying to disguise as a question.

If you want the short answer: encapsulation. I've linked to the wiki page but there is a ton of information available if you look this up in your preferred search engine. The reason I'm mentioning it is to give you a targeted search query to easily find the existing information on the topic.

More to the point for this answer: your implicit point is a moot point. The underlying tone of your question is that access modifiers are an (allegedly unnecessary) complexity. The counterpoint you're making is that if access control was relevant, that it would already make sense that developers would just know whether to access something or not without needing a modifier to express that. This is a self-defeating assertion.

If developers just inherently knew (with no additional effort required) what to touch and what not to touch at which time, they would inherently also just inherently know which access modifier to use, which in turn renders the claim that access modifiers are a complexity a moot point, since the right access would be trivial to know/deduce at all times with no effort required.

On the other hand, if you are going to assert that it's not easy having to decide the correct access modifier for a given field/method/property, then you are in turn proving the point that access control is not self-evident, and therefore explicitly listing it means that the decision can be enshrined so that future developers don't need to go through the repeated effort of having to figure out whether they should be touching this field/method/property or not.

So, which is it? Is access control trivial, or do access modifiers denote something non-trivial? In either case, it counters the underlying basis of your question, which is clearly arguing against the inclusion of access modifiers in the language.

Or, if you prefer an analogy: why do you have doors inside of your house (i.e. that don't connect to the outside world directly)? Do you think there's value to having some privacy in a house that is shared with multiple people, even if they're family? Similarly, we could ask ourselves why houses would even have internal (non-supporting) walls. After all, can't people just keep track of which activity they perform in which part of the house without needing to make explicit boundaries?

6
  • the question is about information hiding, so an article about encapsulation is a poor fit. Also, neither Wikipedia nor your answer make effort to explain why it it needed in the first place (besides vague references to decoupling, which is too close of a term to be useful).
    – Basilevs
    Commented Apr 16 at 5:35
  • 2
    @Basilevs Second sentence of the linked article: "[Encapsulation] may also refer to the limiting of direct access to some of that data, such as an object's components." The article soon continues: "As one example, encapsulation can be used to hide the values or state of a structured data object inside a class, preventing direct access to them by clients in a way that could expose hidden implementation details or violate state invariance maintained by the methods." And that's before we get to an entire chapter titled "Information Hiding" which explains the intention.
    – Flater
    Commented Apr 16 at 6:00
  • @Basilevs: Just to point out the specific parts that you seem to have missed in the linked article: "Hiding the internals of the object protects its integrity by preventing users from setting the internal data of the component into an invalid or inconsistent state. A supposed benefit of encapsulation is that it can reduce system complexity, and thus increase robustness, by allowing the developer to limit the interdependencies between software components." But the core of this answer directly tackles the undertone of the question more than its upfront facade, for reasons already explained.
    – Flater
    Commented Apr 16 at 6:06
  • I read the question as: How does information hiding help managing complexity? Why do we not trust client code to do the right thing to our internals? In other words the question is about rationale, not about term definitions. And the article does not answer that.
    – Basilevs
    Commented Apr 16 at 6:20
  • @Basilevs: Regardless of how you read the question, the actual question is how access modifiers benefit developers. OP's question does not in fact already address concepts such as managing complexity, hence why it's the answer and not the question. The ability to hide internals from mistaken usage by outsiders and a reduction in system complexity by limiting interdependencies, i.e. what I just quoted, is a direct answer to OP's question. You can infinitely shift the goalpost by asking "but why?", but this does not meaningfully contribute to the direct Q&A format as outlined by StackExchange.
    – Flater
    Commented Apr 16 at 6:30
3

In the same way that we have guardrails and painted marking on our roads.

Can't drivers just see where their lane is? Isn't it stupid to drive off the road and crash into a tree? Or drive into oncoming traffic?

Yes. But we are all human. In a theoretic test most people can tell you where their side of the road is, but at a 100 miles an hour in light rain when you are already 15 minutes late, those things sure help. Because compared to the cost of an accident, the cost of having paint on the road is ridiculously low.

So if you are in your own hobby project, with no pressure at all, by all means just make everything public (or leave it out completely, if that is already the default). But in a professional environment, where an error costs a lot of money and you are constantly under pressure, you take all the help and guard rails you get. Why wouldn't you?

0

I agree with @Flater that the short answer is: Encapsulation

However I would expand the answer differently, to say that each protection level represents a contract between the original author and the user/caller of the code.

It is possible that there are a set of invariants, prerequisites etc that must be satisfied by the caller in order for the code to function correctly. The author may be able to define these through their use of types or may need to document them. Given that the caller satisfies these conditions, the author in turn is making some guarantees about the values/functionality that the caller will receive from the code.

Assuming the first protection level was "public" a different protection level, such as "protected" is a second contract, most likely this will extend the requirements of the public contract to require the caller to make additional guaranties and/or implement additional methods in order for the code to continue to work correctly.

Depending upon your language choice there may be additional protection levels such as "package" or "companion" which provide additional contracts that can be used.

Depending upon how you look at it the "private" protection level is either a lack of contract - meaning that no guarantees are made, or the strictest of contracts - that the caller is not allowed to interact with private variables and methods at all.

From a technical perspective there are often work arounds that allow the caller to violate these contracts - however in such cases you lose the guarantees the original author made.

--

Whether protection levels are enforced by a language and tool chain or only through convention is likely a language design choice, I don't think that such a choice affects the previous points.

0

But why would you not want to be able to access an internal property?

The main reason is when you're providing code to be consumed by another programmer you don't control, but you want to retain some predictability about your own freedom to maintain and reconceive the parts behind the public surface.

If you think about the relationship between Microsoft and in-house developers in millions of businesses around the world, that's the most compelling situation envisaged for the use of these controls.

In modern IDEs, access modifiers are also helpful to the suggestions of the Intellisense feature.

And there are a number of patterns where the whole point is to provide a wrapper around certain fields which shouldn't be used directly (because there's some kind of complexity which the wrapper is supposed to relieve).

And if they absolutely should not be accessed, why can programmers not just know not to do it, instead of needing to explicitly define these in the language?

There is an argument about how important access modifiers are in the overall scheme of things. After all, there are many things programmers mustn't do but which aren't enforceable. And there are many languages that don't have the concept of an access modifier.

In practice, the use of access modifiers also requires more powerful debugging facilities which are able to look behind the access controls, at least for debugging purposes.

But it's necessary to set the main context of usage again. It's not reasonable to think that if Microsoft flung open all the innards of its software, that every other developer in the world would "just know" what they should and shouldn't touch.

Frankly, even with my own colleagues, I often don't know exactly what should and shouldn't be touched amongst the things they have devised. And after six months, I often have a fading understanding of what should and shouldn't be touched in my own code!

There can be a temptation to think that language features are amongst the most important things about programming, when in fact they often just reflect facilities that are the easiest (in any given era) to design into the language, with the programmer left to juggle the more difficult and important things.

I think as well though, there is a temptation for enquiring minds to tend to think about programming as a solo activity, and thus to think only about what they need themselves to write an application within their individual capability.

In fact, industrial programming languages are designed in many ways to accommodate the needs of collectives of programmers, including not just organised teams but disorganised practitioners who make and use component libraries, and multiple generations of programmers who may oversee a single codebase.

Many language features whose usefulness is open to dispute in the context of solo development, are necessary without question when development is shared.

Not the answer you're looking for? Browse other questions tagged or ask your own question.