Object oriented encapsulation case
01. Xiaoming loves running
- demand
- Weight 75 kg
- Lose 0.5kg per run
- Eat and gain 1 kg
class Person: def __init__(self,name,weight): # self. Attribute = formal parameter self.name = name self.weight = weight def __str__(self): return "My name is%s Weight is%.2f kg ." % (self.name,self.weight) def run(self): print("%s I love running and exercise" % self.name) self.weight -= 0.5 def eat(self): print("%s Love to eat, eat and gain weight" % self.name) self.weight += 1 xiaoming = Person("Xiao Ming",75.0) xiaoming.run() xiaoming.eat() print(xiaoming) xiaomei = Person("Xiaomei",45.0) xiaomei.run() xiaomei.eat() print(xiaomei) # Multiple objects do not affect each other Xiao Ming loves running and exercises Xiao Ming likes to eat and gain weight My name is Xiao Ming and my weight is 75.50 kg . Xiaomei loves running and exercises Xiaomei likes to eat and gain weight My name is Xiaomei and my weight is 45.50 kg .
02. Placing furniture
- demand
- The house has a list of house type, total area and furniture names
- The new house has no furniture
- Furniture: name and floor area
- Simmons: 4
- Wardrobe: 2
- Table: 1.5
- Add furniture to the house
- Print house output: house type, total area, remaining area, furniture name list
- Remaining area
- Defined when creating objects
- Call add_ Add furniture using the item method
- Which class to develop first?
Furniture category: the furniture category is simple. The house should use furniture. The category used in the development should be developed first
class HouseItem: def __init__(self, name, area): self.name = name self.area = area def __str__(self): return "%s Land occupation %.2f" % (self.name, self.area) bed = HouseItem("Simmons", 4) chest = HouseItem("wardrobe", 2) table = HouseItem("table", 1.5) print(bed) print(chest) print(table) Simmons covers an area of 4.00 The wardrobe covers an area of 2.00 Table area 1.50
Define house class
class HouseItem: def __init__(self, name, area): self.name = name self.area = area def __str__(self): return "%s Land occupation %.2f" % (self.name, self.area) class House: def __init__(self, house_type, area): self.house_type = house_type self.area = area self.free_area = area self.item_list = [] def __str__(self): return ("House type:%s\\n Total area: %.2f\\n Remaining area:%.2f\\n Furniture: %s" % (self.house_type, self.area, self.free_area, self.item_list)) # python can automatically concatenate the code in parentheses def add_item(self,item): print("To add%s" % item) bed = HouseItem("Simmons", 4) chest = HouseItem("wardrobe", 2) table = HouseItem("table", 1.5) print(bed) print(chest) print(table) my_house = House("two bedrooms ", 60) my_house.add_item(bed) my_house.add_item(chest) my_house.add_item(table) Simmons covers an area of 4.00 The wardrobe covers an area of 2.00 Table area 1.50 To add Simmons 4.00 To add a wardrobe 2.00 To add Table 1.50
Complete furniture placement:
class HouseItem: def __init__(self, name, area): self.name = name self.area = area def __str__(self): return "%s Land occupation %.2f" % (self.name, self.area) class House: def __init__(self, house_type, area): self.house_type = house_type self.area = area self.free_area = area self.item_list = [] def __str__(self): return ("House type:%s\\n Total area: %.2f\\n Remaining area:%.2f\\n Furniture: %s" % (self.house_type, self.area, self.free_area, self.item_list)) # python can automatically concatenate the code in parentheses def add_item(self,item): print("To add%s" % item) if item.area > self.free_area: print("%s The area is too large" % item.area) return self.item_list.append(item.name) self.free_area -= item.area bed = HouseItem("Simmons", 4) chest = HouseItem("wardrobe", 2) table = HouseItem("table", 1.5) print(bed) print(chest) print(table) my_house = House("two bedrooms ", 60) my_house.add_item(bed) my_house.add_item(chest) my_house.add_item(table) print(my_house) Simmons covers an area of 4.00 The wardrobe covers an area of 2.00 Table area 1.50 To add Simmons 4.00 To add a wardrobe 2.00 To add Table 1.50 House type: two rooms and one living room Total area: 60.00 Remaining area: 52.50 Furniture: ['Simmons', 'wardrobe', 'table']
03. Soldier assault
The properties of an object can be objects created by another class
- Requirements:
- Soldier Xu Sanduo has a ak47
- Soldiers can fire
- Guns can fire bullets
- The gun is loaded
Guns:
class Gun: def __init__(self, model): self.model = model self.bullet_count = 0 def add_bullet(self, count): self.bullet_count += count def shoot(self): if self.bullet_count <= 0: print("%s There are no bullets" % self.model) return self.bullet_count -= 1 print("%s Protrusion%d" % (self.model, self.bullet_count)) ak47 = Gun("ak47") ak47.add_bullet(50) ak47.shoot() ak47 Protrusion 49
Soldiers:
class Gun: def __init__(self, model): self.model = model self.bullet_count = 0 def add_bullet(self, count): self.bullet_count += count def shoot(self): if self.bullet_count <= 0: print("%s There are no bullets" % self.model) return self.bullet_count -= 1 print("%s Protrusion%d" % (self.model, self.bullet_count)) class Soldier: def __init__(self, name): self.name = name self.gun = None def fire(self): if self.gun == None: print("%s No guns yet" % self.name) return print("Go...%s" % self.name) self.gun.add_bullet(50) self.gun.shoot() ak47 = Gun("ak47") xusanduo = Soldier("Xu Sanduo") xusanduo.gun = ak47 xusanduo.fire() Go...Xu Sanduo ak47 Protrusion 49
Identity operator (supplementary)
Used to compare whether the memory addresses of two objects are the same - whether they are references to the same object
- For the comparison of None in python, it is recommended to use is
- ==Used to determine whether the values of two reference variables are equal
Private properties and private methods
01. Application scenario and definition method
Application scenario
- Some properties and methods of objects do not need to be exposed to the outside world and are only used internally
Definition mode
- Precede the property name or method name with two underscores
class Women: def __init__(self, name): self.name = name self.__age = 18 def secret(self): # Private properties can be accessed inside an object's method print("%s What is your age%d" % (self.name, self.__age)) xiaofan = Women("Xiao Fang") # print(xiaofan.age) xiaofan.secert() Xiao Fang's age is 18
02. Pseudo private properties and private methods (understand)
There are no real private properties and private methods in python
- When naming the given attributes and methods, special treatment is made to the name, resulting in no access to the outside world
- Processing method: add before the name_ Class name ⇒_ Class name__ name
class Women: def __init__(self, name): self.name = name self.__age = 18 def secret(self): # Private properties can be accessed inside an object's method print("%s What is your age%d" % (self.name, self.__age)) xiaofan = Women("Xiao Fang") print(xiaofan._Women__age) xiaofan.secret()
- Subclass objects cannot directly access the private methods and properties of the parent class within their own methods
- Subclasses can access private methods and properties through the public methods of the parent class
inherit
Three object-oriented features:
- encapsulation
- The inherited subclass has the methods of the parent class
- polymorphic
- Syntax:
class Animal: def eat(self): print("eat") **class dog(Animal):**# inherit def bark(self): print("call") dog = dog() dog.bark() dog.eat()
-
Terms: subclass, parent, inheritance
Derived class, base class, derived
-
Transitivity of inheritance
- c inherits b, b inherits a
- Class c has properties and methods of b and a
- Method override
-
If the method of the parent class cannot meet the needs of the child class, the child class needs to override the method
- Override the method of the parent class: rewrite the method implementation of the parent class in the child class (define a method with the same name)
- Extend the parent class method: the parent class method exists in the implementation of the child class method. Override the parent method in the subclass, and execute the parent method through the super(). Parent method where necessary
class Animal: def eat(self): print("eat") class dog(Animal):# inherit def bark(self): print("call") def eat(self): print("Eat bones") super().eat() dog = dog() dog.bark() dog.eat() call Eat bones eat
- Another way to call the parent class method: parent class name. Method (self), which is not recommended (understand)
Multiple inheritance
Concept: a subclass can have multiple parent classes and all the properties and methods of the parent class
Syntax: class subclass name (parent class name 1, parent class name 2)
- During development, if there are methods with the same name in different parent classes, multiple inheritance should be avoided
- MRO in python - method search order:
- Built in objects are provided in python__ mro__ You can view the method search order
- mro is mainly used to determine the call path of methods and properties in multi inheritance
- Output according to__ mro__ The output results of are searched from left to right
- If a method is found in the current class, it will no longer be executed
- If it is not found in the Object class, an error will be reported
Current class → parent class 1 → parent class 2 → object class
New and old
object is the base class provided by python for all objects. It provides some built-in methods and properties, which can be viewed using the dir method function
- New class: a class based on object
- Old style class: a class that does not take object as the base class
class A(object): pass class B: pass a = A() b = B() print(dir(a)) print(dir(b)) # The new version of python defaults to the new class ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
polymorphic
Characteristics: different subclass objects call the same method to produce different execution results
- Can increase code flexibility
- On the premise of inheriting and overriding parent class methods
- Does not affect the internal design of the class
Case drill
demand
- Encapsulating the game method in the dog class
- Define xiaotianquan, inherit dog class and override game method
- Define the person class and encapsulate the methods of playing with dogs
class Dog(): def __init__(self, name): self.name = name def game(self): print("%s Bouncing play" % self.name) class xiaotianquan(Dog): def game(self): print("%s Fly to the sky to play" % self.name) class person(): def __init__(self, name): self.name = name def game_with_dog(self, dog): print("%s and%s Happy play" % (self.name, dog.name)) dog.game() wangcai = Dog("Wangcai") huahua = xiaotianquan("Flying flower") xiaoming = person("Xiao Ming") xiaoming.game_with_dog(wangcai) xiaoming.game_with_dog(huahua) Xiaoming and Wangcai play happily Wangcai's bouncing play Xiao Ming and feitianhua play happily Flying flowers fly to the sky to play
Class properties
01. Structure of class
- Creating objects with class names () is divided into two parts:
- Allocate space in memory
- Call initialization method__ init__ Initialize for object
- After the object is created, an instance exists in memory
- Objects are called instances of classes
- Creating objects is called instantiation
- The properties of the object are instance properties
- The method called by an object is called an instance method
- There is only one method of multiple objects in memory. When calling a method, you need to pass the reference of the object to the method
02. A class is a special object
- class AAA: the defined class belongs to class object
- obj1 = AAA () belongs to the instance object
- There is only one class object in memory. A class can create multiple instance objects
- In addition to encapsulating the properties and methods of instances, class objects can also have their own properties and methods
- Class properties
- Class method
- Access the properties and methods of the class through the method of the class name
03. Class attribute and instance attribute
Concept:
- Class properties are properties defined in class objects
- Relevant characteristics of record class
- Class properties are not used to record specific object characteristics
Example requirements:
- Define a tool class
- Each tool has its own name
- Requirements - do you know how many tool objects have been created using this class?
class Tool(object): count = 0 def __init__(self,name): self.name = name Tool.count +=1 tool1 = Tool("axe") tool2 = Tool("Hammer") tool3 = Tool("bucket") print(Tool.count) 3
Property acquisition mechanism (understand):
-
There is an upward lookup mechanism for getting properties in python
- First, find the object properties inside the object
- If it is not found, it will look up for the class attribute
class Tool(object): count = 0 def __init__(self,name): self.name = name Tool.count +=1 tool1 = Tool("axe") tool2 = Tool("Hammer") tool3 = Tool("bucket") print(tool3.count) # It is not recommended because the count attribute is added to the object 3
Class method
Class method creation:
- Syntax:
@classmethod def Class method name( cls): pass
- cls tells the interpreter that this is a class method
- The cls in the method is the reference of which class is called
- Similar to self
- Other names are also acceptable (not recommended)
- Within the method, you can access class properties through cls. Or call other class methods
Strength requirements:
- Define a tool class
- Each tool has its own name
- Requirements - encapsulate a class method of show_tool_count in the class and output the number of objects created using the current class
class Tool(object): count = 0 @classmethod def show_tool_count(cls): print("Number of tool objects %d" % cls.count) def __init__(self,name): self.name = name Tool.count +=1 tool1 = Tool("axe") tool2 = Tool("Hammer") tool3 = Tool("bucket") Tool.show_tool_count() Number of tool objects 3
Static method
- During development, a method needs to be encapsulated:
- You do not need to access instance properties or instance methods
- There is no need to access class properties and class methods
- At this time, it can be encapsulated into static methods
- Called by class name
- grammar
@staticmethod def Static method name (): pass
Simple example:
class Dog(object): @staticmethod def run(): print("The dog is running") Dog.run() # Access by class name does not require instantiation The dog is running
Method comprehensive case
Requirements:
- Design a Game class
- Properties:
- Define a class attribute top_score to record the highest score in the history of the game
- Define an example attribute player_name to record the player name of the current game
- method:
- The static method show_help displays the help information of the game
- Class method show_top_score displays the highest score in history
- The instance method start_game starts the game of the current player
- Main program steps
- View help information
- View the highest score in history
- Create a game object and start the game
class Game(object): top_score = 0 def __init__(self, player_name): self.player_name = player_name @staticmethod def show_help(): print("Help information:") @classmethod def show_top_score(cls): print("Historical records%d" % cls.top_score) def start_game(self): print("%s Start the game" % self.player_name) Game.show_help() Game.show_top_score() game = Game("Xiao Ming") game.start_game() Help information: History 0 Xiao Ming starts the game
Single case
01. Single case design mode
Design mode:
- Design pattern is the summary of previous work and a mature solution to a specific problem
- In order to reuse the code, make the code easier to understand
Single example design mode:
- Purpose - let the object created by the class have only one instance in the system
- Each time the class name () is executed, the returned object has the same memory address
**new method:**
- When you create an object with the class name (), you will first call the _new _ () method to allocate space for the object
- The new() method is a built-in static method
- Allocate space for objects
- Return object reference
- After the interpreter obtains the object reference, it passes the reference as the first parameter to the _init _method
- When overriding _ new _ () method, be sure to return super(). new(cls)
class MusicPlayer(object): def __new__(cls, *args, **kwargs): print("Create objects and allocate space") return super().__new__(cls) def __init__(self): print("Player initialization") player1 = MusicPlayer() player2 = MusicPlayer() print(player1) print(player2) Create objects and allocate space Player initialization Create objects and allocate space Player initialization <__main__.MusicPlayer object at 0x0000028CFCFB3E50> <__main__.MusicPlayer object at 0x0000028CFCFB3E20>
- Code implementation of singleton design pattern
class MusicPlayer(object): # Record the reference of the first object created instance = None def __new__(cls, *args, **kwargs): # Judge whether the class attribute is an empty object if cls.instance is None: # Call the parent method to allocate space for the first object cls.instance = super().__new__(cls) return cls.instance player1 = MusicPlayer() player2 = MusicPlayer() print(player1) print(player2) <__main__.MusicPlayer object at 0x0000024C8E613EE0> <__main__.MusicPlayer object at 0x0000024C8E613EE0>
Extension:
-
Each time you create an object, python automatically calls two methods:
- __new_ allocate space
- __init_ object initialization
-
The initialization method is also called when the object is created
-
Requirement: let the initialization method execute only once
-
resolvent:
- Defines whether the class attribute init_flag flag flag performs an initialization action
- Determine the init_flag in _init_
class MusicPlayer(object): # Record the reference of the first object created instance = None # Record whether the initialization method has been executed init_flag = False def __new__(cls, *args, **kwargs): # Judge whether the class attribute is an empty object if cls.instance is None: # Call the parent method to allocate space for the first object cls.instance = super().__new__(cls) return cls.instance def __init__(self): # Determine whether to execute initialization action if MusicPlayer.init_flag: return # Perform initialization action print("Initialize player") # Modify tag value MusicPlayer.init_flag = True player1 = MusicPlayer() player2 = MusicPlayer() print(player1) print(player2) Initialize player <__main__.MusicPlayer object at 0x0000022EE6713E80> <__main__.MusicPlayer object at 0x0000022EE6713E80>