Steve, I think that your definition of encapsulation is too wide to give
a reasonable answer to the question at hand.
My definition of encapsulation is based on the plain language definition.
It is also common in computer programming circles to talk about
encapsulation in this way. OOP designers may (or may not) have been the
first to declare "encapsulation" was a design principle, but programmers
have been using the *principle* of encapsulation since before Grace
Hopper was an admiral.
See, for example, coders talking about encapsulation in C and Powershell:
http://ejrh.wordpress.com/2011/04/29/encapsulation-in-c/
https://www.simple-talk.com/dotnet/.net-tools/further-down-the-rabbit-
hole-powershell-modules-and-encapsulation/
OOP languages give us *more* and *better* ways to encapsulate code and
data, but they did not invent the principle.
If I understand you
correctly, you are taking encapsulation as a language characteristic,
rather than a principle.
No, it is both. The coder may or may not decide to encapsulate code in
subroutines/functions/classes, and the language may or may not allow it.
Languages differ in their ability to allow the programmer to encapsulate.
Some languages, like early BASIC, give you no ability to encapsulate code
or data at all. All variables are global, and there are no functions,
just a big blob of code in a single file. There aren't even data
structures as such, except strings, so you cannot even group related
pieces of data into a struct or record.
Some languages, like Python, give you many ways to encapsulate code and
data: you can group related code in a function, related functions in a
class, related classes in a module, related modules in a package. That's
pretty much exactly the same sort of things that you can do in Java. C++
has an additional "namespace" data structure that Python doesn't have,
but that's just a mechanism for encapsulation.
Encapsulation and information hiding are distinct things -- you can have
one without the other. C, for example, creates a new scope inside for-
loops, so that the for-loop variable is hidden from the rest of the
function. Apart from a pair of braces, there is no encapsulation, but
there is information hiding. Or you could design a language that
encapsulated code into functions and classes, but put all variables in a
single, global, shared namespace (little, or no, information hiding).
It is a myth, and a very obnoxious one, that encapsulation and
information hiding were invented by OOP. What is a function but a way to
hide the implementation of a chunk of code from the caller? What are
local variables but a way to hide variables used by one function from
another? Coders were using information hiding, separation of concerns,
and encapsulation in the 1950s, long before OOP. They just didn't call
them by those names. They just called them "writing good code".
Actually, functions are *not necessarily* a way to hide implementation.
There are languages where you can jump into the middle of a function. So
you can encapsulate a chunk of code into a function, without hiding the
implementation details. Just as you can encapsulate code and data into a
class, without hiding the implementation details, if you declare
everything public.
Plus, you seem to forget that encapsulation is
an OOP principle, and, forgive me if I am wrong, does not apply normally
to functions or languages like C.
I haven't forgotten it, because it isn't true.
One of the most obnoxious and annoying traits of OOP zealots, especially
academics, is that they act as if programming did not exist before Java
and C++, or if you're really lucky, Smalltalk. (Somehow they nearly
always forget about Simula.) Perhaps because OOP was so late to be
invented (structured programming goes back to Fortran in the 1950s,
functional programming to Lisp only a few years after that), and because
it was so heavily hyped as "the solution" to every programming
difficulty, too many people ignore anything outside of the OOP. They
wrongly believe that since Python isn't a "pure" OOP language (according
to some bizarre understanding of "pure" that often considers C++ and Java
pure), Python cannot possibly have "OOP principles" like encapsulation,
information hiding, separation of concerns.
That point of view is sheerest nonsense.
Please read Steve Holden's (in chaz')
definition, and tell us whether you think that Python enforces strongly
this principle, I think that would be a good basis for an agreement.
Are you referring to this quote?
"encapsulation is the idea that the only way to access or change the data
inside an object is by calling its methods."
I disagree with that definition. That's a poor definition, one that has
no relation to the plain English meaning of the word "encapsulation", nor
to how the word is commonly used in the great bulk of programming
circles. By referring to "objects" and "methods" it wrongly assumes that
encapsulation can only apply to OOP.
I quote from The Free On-line Dictionary of Computing:
encapsulation
1. The technique used by layered protocols in which a layer
adds header information to the protocol data unit (PDU) from
the layer above. As an example, in Internet terminology, a
packet would contain a header from the physical layer,
followed by a header from the network layer (IP), followed by
a header from the transport layer (TCP), followed by the
application protocol data.
2. The ability to provide users with a well-defined interface
to a set of functions in a way which hides their internal
workings. In object-oriented programming, the technique of
keeping together data structures and the methods (procedures)
which act on them.
Definition 1 is irrelevant to this discussion, but definition 2 makes it
absolutely clear that it is not just about OOP.
My
answer is no, it doesn't, but it allows you to abide by it if you want
to. Unlike Java or C++ who would tend to do exactly the contrary
(enforces it strictly, and (possibly?) allow you to discard it at times
with a few jiffies (or not? I don't know))
Java and C++ allow you to declare members as public, so it is *not true*
that calling methods is the only way to change members. If you accept
Steve Holden's (wrong) definition above, Java and C++ don't have
encapsulation either.