面向对象总结
基础概念
静态属性\私有属性
class Person(object): COUNTRY = '牧师' #静态属性 __MAGE = '法师' # 私有静态属性,只能在类的内部使用,外部无法直接操作 def __init__(self,name,age): #self是一块内存空间,实例化后会存放属性的值 self.name = name #属性,属于对象的值 --对象属性 self.__age = age #对象的私有属性 ,私有属性不能被继承,只能在类的内部使用,外部无法直接操作 def running(self): #类的方法,方法自带self参数,动态属性 print('%s running'%self.name) #使用对象属性 print(self.__age) #使用对象的静态属性 print(Person.COUNTRY) #查看类的静态属性 类名.静态属性名 ret = Person('wanglan',18) #ret:对象 实例化 print(ret.name) #使用对象查看对象属性 ret.running() #使用对象调用类中的方法
概念
什么是类:具有相同属性和方法的一类事事物 什么是对象:对象是类中一个具体的例子(拥有具体的属性值和具体的方法),对象就是类的实例化,类的实例 什么是实例:实例完全和对象是一样的 什么是实例化:由类创建对象的过程 实例化的过程:1.创建一个属于对象的空间 2.将这个空间的地址和参数传递给__init__方法 3.执行init方法,4.将对象的空间返回给对象名 静态属性:所有的这个类的对象都共有的属性 什么是对象的属性:存储在实例化之后创建的空间中的所有变量都是对象的属性,每一次实例化产生的空间都是独立的,每一个对象都有自己的属性值 对象能做什么:调用对象的属性,调用类中的方法(动态属性) 什么是动态属性:定义在类中的函数,自带一个self属性
类中的代码在实例化之前执行
类的命名空间中有静态属性和动态方法
__dict__
class Person(object): NAME = 'WL' def __init__(self,name,age): self.name = name self.age = age def func(self): print(self.name) print(self.age) person = Person('wanglan','18') print(Person.__dict__) #类名.__dict__,查看类中的变量,属性,不能操作,只能查看 print(person.__dict__) #对象名.__dict__会将对象属性和值以字典的方式打印出来 print(person.__dict__['name']) #取值
操作属性的值
class Person(object): NAME = 'WL' def __init__(self,name,age): self.name = name self.age = age def func(self): print(self.name) print(self.age) person = Person('wanglan','18') #查看属性值 print(person.name) # 修改属性的值 person.name = 'wl' print(person.name) #添加一个属性 person.gender = '男' print(person.gender) #删除属性的值 del person.gender print(person.gender)
对象之间的交互
class Dog: def __init__(self,name,kind,hp,ad): self.name = name self.kind = kind self.hp = hp self.ad = ad def bite(self,person): print('%s咬人%s'%(self.name,person.name)) person.hp -= self.ad if person.hp <= 0 : print('%s死了'%person.name) person.hp = 0 # 实例化一些对象 xm = Person('xiaoming','男',10,10,100) eh = Dog('二哈','金毛',9999,998) print(eh.hp) #查看二哈的hp xm.attack(eh) #小明攻击了二哈, print(eh.hp) # 再次查看二哈的hp print(xm.hp) #查看小明的hp eh.bite(xm) #二哈咬了小明 print(xm.hp) #再次查看小明的hp
一个类中可以没有__init__
class A: Country = 'China' def talk(self): print('%s is talking'%self.name) xm = A() xm.name = 'alex' xm.talk() # 在没有__init__的情况下,实例化经历了哪些步骤??? # 1.创建一个空间给对象 # 2.将这个空间的地址返回
对象的命名空间和类的命名空间之间的关系
对象和类之间有一个单向的联系,类对象指针
对象在使用某个名字的时候,如果在自己的空间中没有找到,就要到类的空间中去找
class A: Country = 'China' # 静态属性就是用来描述所有的对象都共享的某一个值 def __init__(self,name): self.name = name def talk(self): print('%s is talking'%self.name) xiaogao = A('xiaogao') print(xiaogao.Country) xiaogao.Country = '泰国' #在xiaogao中创建,并不是去找静态属性 print(xiaogao.Country) # '泰国' del xiaogao.Country print(xiaogao.Country) # 'China' print(A.Country)
对象可以查看类的静态属性,但是不能修改,并且一旦修改,就不能取到类当中的内容了(除非手动删除这个修改的属性),所有的静态属性的修改,都应该由类名来完成,而不应该使用对象名来完成
组合
圆形类/环形类
from math import pi class Circle: def __init__(self,r): self.r = r def area(self): return pi*self.r**2 def perimeter(self): return 2*pi*self.r c1 = Circle(10) print(c1.area()) print(c1.perimeter()) class Ring: def __init__(self,outer_r,inner_r): self.out_c = Circle(outer_r) # Circle(10) self.in_c = Circle(inner_r) # Circle(5) def area(self): return self.out_c.area() - self.in_c.area() def perimeter(self): return self.out_c.perimeter() + self.in_c.perimeter() r1 = Ring(10,5) print(r1.area()) print(r1.perimeter())
class Birthday: def __init__(self,year,month,day): self.year = year self.month = month self.day = day class Student: def __init__(self,name,sex,birth_day): self.name = name self.sex = sex self.birthday = birth_day birth = Birthday(1996,9,13) bobo = Student('bobo','male',birth) # birth == bobo.birthday # birth.year print(bobo.birthday.year)
pickle :游戏人物状态的保存(存档读档)练习
pickle模块可以序列化python中的所有自定义类的对象
import pickle class Course: def __init__(self,name,age,gender): self.name = name self.age = age self.gender = gender def __str__(self): return ('%s %s %s' %(self.name,self.age,self.gender)) xl = Course('xiaoming',18,'男') print(xl) with open('courses','wb') as f: pickle.dump(xl,f) #写入文件 with open('courses','rb') as f: ret = pickle.load(f) print(ret)
如果load一个对象,那么这个对象所对应的类必须已经在内存中
同一个类的对象 会存储在同一个文件中
继承
继承 : 就是为了解决类与类之间代码重复的问题的
类的继承的语法
单继承
class A:pass class B(A):pass print(A.__bases__) #查看父类 print(B.__bases__) 结果: (<class 'object'>,) #类默认继承onject (<class '__main__.A'>,) #B继承了A
多继承
class A:pass class B:pass class C(A,B):pass print(A.__bases__) print(B.__bases__) print(C.__bases__) 结果: (<class 'object'>,) (<class 'object'>,) (<class '__main__.A'>, <class '__main__.B'>)
子类可以继承父类的方法和属性
子类调用方法,如果子类自己有用自己的,用了自己的就不用父类的了
如果子类自己没有才调用父类的
如果子类有个性化的父类没有的方法,可以单独定义在子类中 - 派生方法
只有子类能够使用父类中的方法,父类不可以使用子类中的方法
当某一个方法,父类和子类都拥有的时候,那么在子类的方法中,调用父类的同名方法
1.父类名.方法名(self,...)
2.super().__init__(...)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Animal: def __init__(self,name,hp,ad): self.name = name self.hp = hp self.ad = ad class Person(Animal): def __init__(self,name,sex,hp,mp,ad): super().__init__(name,hp,ad) self.sex = sex # 派生属性 self.mp = mp # 派生属性 def attack(self,dog): print('%s攻击了%s'%(self.name,dog.name)) dog.hp -= self.ad class Dog(Animal): def __init__(self,name,kind,hp,ad): super().__init__(name,hp,ad) self.kind = kind # 派生属性 def bite(self,person): print('%s咬了%s'%(self.name,person.name)) person.hp -= self.ad alex = Person('alex','不详',10,10,0.1) hei = Dog('小黑','中华田园犬',999,1.1) print(hei.__dict__)
归一化/抽象类
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from abc import ABCMeta,abstractmethod #抽象方法 class Payment(metaclass=ABCMeta): #metaclass = ABCMeta表示Payment类是一个规范类 @abstractmethod # @abstractmethod表示下面一行中的pay方法是一个必须在子类中实现的方法 def pay(self):pass class AliPay(Payment): def __init__(self,name): self.name = name def pay(self,money): # 支付宝提供了一个网络上的联系渠道 print('%s通过支付宝消费了%s元'%(self.name,money)) class WeChatPay(Payment): def __init__(self,name): self.name = name def pay(self,money): # 微信提供了一个网络上的联系渠道 print('%s通过微信消费了%s元'%(self.name,money)) # 归一化设计 : 从原来的面向对象编程 -->面向函数编程.降低了用户的使用成本 def pay_func(person,payway,money): if payway == 'alipay': per = AliPay(person) elif payway == 'wechatpay': per = WeChatPay(person) per.pay(money) pay_func('WL','wechatpay',200)
接口类
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
rom abc import ABCMeta,abstractmethod class Fly_Animal(metaclass=ABCMeta): @abstractmethod def fly(self): print('爷会飞') class Swim_Animal(metaclass=ABCMeta): @abstractmethod def swim(self): pass class Walk_Animal(metaclass=ABCMeta): @abstractmethod def walk(self): pass class Swan(Fly_Animal,Swim_Animal,Walk_Animal): def fly(self): super().fly() print('飞') def walk(self):print('走') def swim(self):print('游') class Tiger(Walk_Animal,Swim_Animal): def walk(self):print('走') def swim(self):print('游') class Parrot(Fly_Animal,Walk_Animal): def fly(self):print('飞') def walk(self):print('走') def talk(self):print('说')
c3算法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
每一个类的继承顺序都是从基类向子类看 形成一个指向关系的顺序[当前类] + [父类的继承顺序] 进行一个提取 如果一个类出现从左到右的第一个顺序上,并且没有出现在后面的顺序中,或者出现在后面顺序了,但是仍然是第一个,那么就把这个类提取出来
super在多继承中的意义
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class A: def func(self):print('A') class B(A): def func(self): super().func() print('B') class C(A): def func(self): super().func() print('C') class D(B,C): def func(self): super().func() print('D') d = D() d.func() print(D.__mro__)