In the paradigm of object orientation, there is what is called encapsulation of properties and methods. It is quite common to find materials in which it is said that the function of encapsulation is to protect the data of an object, which in a way is true, but not in the sense of keeping inaccessible when external to the class. Encapsulation serves for you to define business rules that apply to your properties when done interface with the outside world.
It is common in programming languages to define three levels of encapsulation: public, protected and private. When defined as public, no business rule is required of the property, so it is allowed to be defined directly when external to the class. When defined protected, business rules will apply only when the value comes from outside the class, but classes derived from it are free to define new values directly. When defined as private, only the class itself has the freedom to define values directly; from any other source the business rules will apply.
Business rules are applied to properties through methods getter/Setter.
For the examples below, it was considered a hypothetical, dynamic typing programming language. Class names, methods and properties were generated randomly and have no direct relation to the logic presented.
Considering the definition below of a class with three properties, each with its encapsulation level:
class Foo:
private meeten
protected festal
public tamera
Where the properties protected and private must have business rules, methods are defined getter/Setter for each:
class Foo:
private meeten
protected festal
public tamera
public getMeeten ():
...
public setMeeten (value):
...
public getFestal ():
...
public setFestal (value):
...
Since the above mentioned methods are responsible for the interface of properties with the external environment, it is of paramount importance that they are defined with encapsulation public.
It is now considered some business rules for the application:
meeten
must be the type string
with a maximum of 255 characters;
festal
must be the type int
between 0 and 255;
The implementation of these rules would be something similar to:
public setMeeten (value):
if (type(value) != "string"):
throws TypeError;
else if (len(value) > 255):
throws InvalidArgumentException;
this.meeten = value
public setFestal (value):
if (type(value) != "int"):
throws TypeError;
else if not (0 <= value <= 255):
throws InvalidArgumentException;
this.festal = value
With this it is already possible to understand the protection that the encapsulation generates. Once the business rules are defined, it can be considered that the application will not work when they are not valid. For example, if the property meeten
is an integer value. Using the above class, trying to assign an integer to meeten
:
inst = Foo()
inst.setMeeten(1)
An exception of the type TypeError
would be fired. This is the protection that encapsulation defines. As the application would not work properly when meeten
is of the whole type, it forces the value to go through the method setter
where business rules are validated. If invalid, the execution flow of the program is changed by the exception, preventing the erroneous execution of the application.
Same goes for the property protected, however, it is considered that in derived classes, the "know what you’re doing" application, then it is given the freedom to directly change the value of the property. For example:
class Bar extend Foo:
public cheetah ():
this.festal = 10
The class is allowed Bar
directly access the property this.festal
, however, understand that if a value is assigned to the property that does not validate the business rules, for example assign a string
à festal
who should be the int
:
this.festal = "anything"
No exception will be triggered and the application can run normally, probably generating an unexpected result. In these cases, it is recommended, even if you have the freedom to access the property directly, to make use of the method setter
so as to centralize all business rules in just one place of code.
The properties of the type public are usually so defined when there are no business rules, in which the application would work in an expected way for any type of input.
Obviously, details of this function may vary depending on the language considered. For example, in C++, if a property is defined as private or protected and is tried to access it directly in the external middle of the class, an error will be triggered. Already in Python this encapsulation does not exist. At most, Python remakes the properties and methods started with __*
for _Classname__*
, so a property called __foo
in class Bar
would be remapped to _Bar__foo
, but direct access to the latter is released, considering access from the external medium Bar._Bar__foo = 0
without error. This is because in Python it is considered that the developer has knowledge of what he is doing, so he is given all this freedom. In C++ (and I believe that Java), it is already a little more rigid, requiring the use of methods getter/setter
. In Python, start the property name with __
It’s basically to say to the developer afterwards, "Hey, maybe it’s not a good idea to access this directly. Do this only if you really know what you’re doing.". In C++ it would be "Don’t do this!".
In short, encapsulation only creates a protection for your application to work as it should, defining the class’s "entry ports". In no way does it protect your code from a user accessing it, if it has access to your server and source code. For this, you can read more about on How to protect source code?, as quoted in the comments.
Related: How to protect source code?
– Math
No, especially in Python, because there is no such encapsulation in the language, the only thing it does is rename the properties started in
__*
for_Classname__*
. That is, it would still be possible to change them from outside the class withobj._Conta__saldo = 999999
. Behold here.– Woss