The meaning of the term “encapsulation” is vague and differs from source to source. It is generally accepted that encapsulation is one of the fundamental principles of OOP, although some scientific articles completely omit encapsulation from the list. For example, John Mitchell in the book "Concepts in programming languages" when enumerating the main concepts in the PLO mentions only abstraction - a term which is considered to be close to encapsulation in meaning, but still more extensive and high-level. On the other hand, Robert Martin in his book “Pure Architecture” clearly indicates that encapsulation, inheritance and polymorphism is considered the foundation of the PLO.
The variety of definitions given to the term “encapsulation” is difficult to bring to a common denominator. In general, there are two approaches to the meaning of this term. Encapsulation can be viewed as:
This kind of interpretation of the term "encapsulation" is very simple to explain. In this case, any class in which there is at least one variable and one method that controls it clearly demonstrates this principle.
#!/usr/bin/python3 class Phone: number = "111-11-11" def print_number(self): print( "Phone number is: ", self.number ) my_phone = Phone() my_phone.print_number() input( "Press Enter to exit" )
The “Phone” class combines the data in the “number” variable with the “print_number ()” method
You can create a class that consists only of methods (and does not contain variables), which can be convenient in some programming languages. It is also possible to create a class containing only data, without methods, which, in many cases, should be avoided. Both practices should be applied when necessary, and their relationship to “unifying” encapsulation is debatable.
Explaining the concept of restricting access to data or methods requires much more detail. First of all, in this context, the term “access” should be understood as the ability to see and / or change the internal contents of a class. There are several levels of access provided by most OOP languages. Summarizing we can say that the object data can be:
public
) - data is available to all;private
) - data is available only to the object / class to which they belong.Most languages have additional access levels that lie between these boundaries. For example, in C ++ and Python3 there are three levels of access: public, secure, and private; C # adds the keyword "internal" to the list.
It should be noted that in most programming languages, the level of access to any data is set by default. For example, in C ++, the default data access level in a class is set as private — only class members and friends can access its data. The standard level of access to a structure ( struct
) in C ++ is different - it is public, and data in such a structure can be accessed by anyone. The level of access for class variables and methods in Python 3 is entirely dependent on syntax.
Python 3 provides 3 levels of data access:
public
, no particular syntax, publicBanana
);protected
, one underscore at the beginning of the name, _protectedBanana
);private
, two underscores at the beginning of the name, __privateBanana
).For brevity and simplicity, only two basic levels (private and public) are covered in the example.
#!/usr/bin/python3 class Phone: username = "Kate" # public variable __how_many_times_turned_on = 0 # private variable def call(self): # public method print( "Ring-ring!" ) def __turn_on(self): # private method self.__how_many_times_turned_on += 1 print( "Times was turned on: ", self.__how_many_times_turned_on ) my_phone = Phone() my_phone.call() print( "The username is ", my_phone.username ) # my_phone.turn_on() # my_phone.__turn_on() # print( “Turned on: “, my_phone.__how_many_times_turned_on) # print( “Turned on: “, my_phone.how_many_times_turned_on) # will produce an error input( "Press Enter to exit" )
Access to public variables and methods can be obtained from the main program. Attempting to get private data or run a private method will result in an error.
The language itself provides the programmer with a syntactic tool that can bypass encapsulation. Reading and modifying private variables and calling private functions is still possible.
#!/usr/bin/python3 class Phone: username = "Kate" # public variable __serial_number = "11.22.33" # private variable __how_many_times_turned_on = 0 # private variable def call(self): # public method print( "Ring-ring!" ) def __turn_on(self): # private method self.__how_many_times_turned_on += 1 print( "Times was turned on: ", self.__how_many_times_turned_on ) my_phone = Phone() my_phone._Phone__turn_on() my_phone._Phone__serial_number = "44.55.66" print( "New serial number is ", my_phone._Phone__serial_number ) input( "Press Enter to exit" )
There are methods, so-called “magic methods” (“magic methods”) or “special methods” (“special methods”), which allow classes to define their behavior with respect to standard language operators. The following expressions can serve as an example of such language operators:
x > y
x[ i ]
Python 3 supports many of these methods; a full list can be found on the official language documentation page. __init__
(initializer) is the most frequently used one and is launched when creating a new class object. The other, __lt__
(extended comparison), defines rules for comparing two objects of a custom class. Such methods do not fall into the category of “private” or “public”, since they serve other purposes and are deeply rooted in the internal structure of the language.
#!/usr/bin/python3 class Phone: def __init__(self, number): # magic method / inititalizer print( "The Phone object was created" ) self.number = number def __lt__(self, other): # magic method / rich comparison return self.number < other.number my_phone = Phone(20) other_phone = Phone(30) if my_phone < other_phone: print( "Two instances of custom class were compared" ) print( "'__lt__' was called implicitly" ) if my_phone.__lt__(other_phone): print( "Now, '__lt__' was used explicitly" ) input( "Press Enter to exit" )
Magic methods can be invoked by any user in the same way as any public method in Python, however they are intended for implicit use in their particular cases. A special case for the __init__
method is the initialization of a new class object. __lt__
serves to compare two objects.
Python3 does not provide limited access to any class variable or method. Data that should be hidden can actually be read and modified. In Python3, encapsulation is more of a convention, and the programmer must take care of saving it on its own.
Source: https://habr.com/ru/post/444338/
All Articles