Python advanced (6): polymorphism, encapsulation, python advanced
Yesterday, I talked about inheritance of the three object-oriented features. Today, for polymorphism and encapsulation, many other programmers say that python does not support polymorphism and no polymorphism. It is not that python does not have polymorphism, but that python is multi-state everywhere. Today's lectures will focus on encapsulation.
I. Polymorphism
1. Polymorphism
Polymorphism refers to a type of things with multiple forms.
Water has various forms: Ice Water Mist
Animals have many forms: Humans, dogs, and pigs.
Import abcclass Animal (metaclass = abc. ABCMeta): # the same thing: Animal @ abc. abstractmethod def talk (self): passclass People (Animal): # Animal form: Human def talk (self): print ('Say hello ') class Dog (Animal ): # Animal morphology 2: Dog def talk (self): print ('say wangwang') class Pig (Animal): # Animal morphology 3: Pig def talk (self ): print ('say aoao ')Polymorphism
There are multiple forms of Files: text files, executable files
Import abcclass File (metaclass = abc. ABCMeta): # the same thing: file @ abc. abstractmethod def click (self): passclass Text (File): # One of the file forms: Text File def click (self): print ('Open file') class ExeFile (File ): # file Format 2: Executable file def click (self): print ('execute file ')File
2. Polymorphism
Polymorphism refers to the use of instances without considering the instance type.
In the object-oriented method, polymorphism is expressed as follows:
Send the same message to different objects. Different objects may have different behaviors (I .e., methods) during receiving ). That is to say, each object can respond to common messages in its own way. A message is called a function. Different actions refer to different implementations, that is, executing different functions.
For example, teacher. the bell rings (), student. when the next class bell rings (), the teacher performs off-duty operations and the students perform out-of-school operations. Although the messages are the same, the results are different.
Peo = People () dog = Dog () pig = Pig () # peo, dog, and pig are all animals, as long as it is an animal, there must be a talk method # So we can directly use peo without considering the specific types of the three. talk () dog. talk () pig. talk () # further, we can define a unified interface to use def func (obj): obj. talk ()
Polymorphism
3. Duck type
Python advocates the duck type, that is, 'If it looks like a duck, it sounds like a video and starts to look like a duck, then it is a duck 'python programmers usually write programs based on this behavior. For example, if you want to write a custom version of an existing object, you can inherit this object or create a new object with no relationships with it, the latter is usually used to save the loose coupling of program components.
Example 1: using various objects defined in the standard library that are similar to files, although these objects work like files, they do not inherit the built-in file objects.
Example 2: sequence types have multiple forms: strings, lists, and tuples, but they have no direct inheritance relationships.
Example
Ii. Encapsulation
Encapsulation: hides the attributes and implementation details of an object and only provides public access.
Benefits:
1. Isolate changes;
2. ease of use;
3. improve reusability;
4. Improve security;
Encapsulation principles:
1. Hide all content that does not need to be provided externally;
2. Hide all attributes and provide public methods to access them.
1. Private Variables
# In fact, this is only A type of deformation operation # All the names starting with double underscores in the class, such as _ x, will be automatically deformed into the form of _ class name__ x: class: _ N = 0 # The data attribute of the class should be shared, but the data attribute of the class can be set to private, for example, _ N, it will be changed to _ a0000n def _ init _ (self): self. _ X = 10 # deformation is self. _ a1_x def _ foo (self): # Deformation: _ A _ foo print ('from A') def bar (self): self. _ foo () # It can be accessed through _ foo only within the class. #. _ a0000n is accessible, that is, this operation does not strictly restrict external access, but is just a syntactic deformation.Private variable
Features:
1. The _ x defined in the class can only be used internally. For example, self. _ x references the deformation result.
2. This type of deformation is actually an external deformation, which cannot be accessed externally by the name of _ x.
3. The _ x defined in the subclass does not cover the _ x defined in the parent class, because the _ subclass name _ x is transformed: _ parent class name__ x, that is, when the attributes starting with the double-downlink slide are inherited to the subclass, The subclass cannot be overwritten.
Note:
This mechanism does not actually limit direct access to attributes from the outside. When we know the class name and attribute name, we can spell out the name: _ class name_attribute, and then we can access it, such as. _ a0000n
2. Private methods
In inheritance, if the parent class does not want the subclass to overwrite its own method, you can define the method as private
# Normally class A: def fa (self): print ('from A') def test (self): self. fa () class B (A): def fa (self): print ('from B ') B = B () B. test () # from B # define fa as private, that is, _ faclass A: def _ fa (self ): # The definition is changed to _ A _ fa print ('from A') def test (self): self. _ fa () # is only subject to the class where you are located, that is, call _ A _ fa class B (A): def _ fa (self ): # deformation is defined as _ B _ fa print ('from B ') B = B () B. test () # fromPrivate Method
3. scalability
Encapsulation is to clearly distinguish between internal and external, so that the class implementer can modify the content in the encapsulation without affecting the code of the external caller. The external caller only knows one interface (function), as long as the interface (function) the name and parameter remain unchanged, and the user's code never needs to be changed.
# Class designer class Room: def _ init _ (self, name, owner, width, length, high): self. name = name self. owner = owner self. _ width = width self. _ length = length self. _ high = high def tell_area (self): # The interface provided externally hides the internal implementation details. In this case, we want to return the area self. _ width * self. _ length # user r1 = Room ('bedroom ', 'egon', 20, 20, 20) r1.tell _ area () # user calls interface tell_area # class designer, the function is easily extended, and class users do not need to change their own code class Room: def _ init _ (self, name, owner, width, length, high ): self. name = name self. owner = owner self. _ width = width self. _ length = length self. _ high = high def tell_area (self): # provides external interfaces to hide internal implementations. What we want to do now is the volume, and the internal logic has changed, you only need to repair the following line for simple implementation, and the method is still used if the external call is not aware, but the function has changed to return self. _ width * self. _ length * self. _ high # for people who are still using the tell_area interface, they can use the new function r1.tell _ area () without modifying their own code ()Scalability
4. property attributes
''' Example 1: BMI index (bmi is calculated, but it sounds like an attribute rather than a method. If we make it an attribute, it is easier to understand) adult BMI values: Light: less than 18.5 normal: 18.5-23.9 overweight: 24-27 Obesity: 28-32 very obese, higher than 32 Body Mass Index (BMI) = weight (kg) weight height ^ 2 (m) EX: 70kg weight (1.75 × 1.75) = 22.86 ''' class People: def _ init _ (self, name, weight, height ): self. name = name self. weight = weight self. height = height @ property def bmi (self): return self. weight/(self. height ** 2) p1 = People ('egon', 75, 1.85) print (p1.bmi)BMI Index
Import mathclass Circle: def _ init _ (self, radius): # radius self of the Circle. radius = radius @ property def area (self): return math. pi * self. radius ** 2 # Calculated area @ property def perimeter (self): return 2 * math. pi * self. radius # Calculate perimeter c = Circle (10) print (c. radius) print (c. area) # accessing area like accessing data properties will trigger the execution of a function and dynamically calculate a value of print (c. perimeter) # output result: 314.159265358979362.83185307179586 ''' # Note: The attribute area and perimeter cannot be assigned a value c. area = 3 # assign a value to the feature area ''' and throw an exception: AttributeError: can't set attribute '''
Circumference and area of the circle
After a function of a class is defined as a feature, obj is used when the object is used again. name. It cannot be noticed that your name is executed by a function and then calculated. The usage of this feature follows the principle of unified access.
...
(Updates will continue tomorrow)