day28 Pyhton 面向对象 继承
1.昨日回顾
类的命名空间
静态属性\动态属性(方法)
对象的命名空间
#对象的属性
#类指针:对象能够通过这个类指针找到类
#静态属性:属于类,多个对象共享这个资源
#尽量用类名来操作静态属性
#对象操作静态属性:
#只要是给'对象.属性名'赋值就相当于新建对象属性,而不是修改静态属性
#组合
#两个类的对象
#其中一个对象的属性是另一个对象
# class Course: # def __init__(self,name,price,period): # self.name = name # self.price = price # self.period = period # class Student: # def __init__(self,name,sex,age,course_obj): # course_obj = python # self.name = name # self.sex = sex # self.age = age # self.course = course_obj # self.course = course_obj = python # python = Course('python',19800,'6 months') # qi = Student('齐轸棠','女',18,python) # bu = Student('卜鑫杰','男',30,python) # print(qi.course.name) # print(bu.course.name) # python.name = 'python2.0' # print(qi.course.name) # print(bu.course.name)
2.今日内容
(1)
#什么是函数,什么是方法
从定义的角度上看,我们知道函数(function)就相当于一个数学公式,它理论上不与其它东西关系,它只需要相关的参数就可以。所以普通的在module中定义的称谓函数是很有道理的。
那么方法的意思就很明确了,它是与某个对象相互关联的,也就是说它的实现与某个对象有关联关系。这就是方法。虽然它的定义方式和函数是一样的。也就是说,在Class定义的函数就是方法。
方法和函数其实是一样的,只是不同语言的不同表述形式。一般来说,面向过程的语言会使用“函数”来描述,面向对象的语言会用“方法”来描述。
# 从程序的角度上也是可以判断的 # from types import MethodType, FunctionType # print(isinstance(a.func,MethodType)) # print(isinstance(A.func,MethodType)) # print(isinstance(a.func,FunctionType)) # print(isinstance(A.func,FunctionType)
# pickle 游戏人物的状态的保存(存档读档) import pickle # python # pickle模块可以序列化python中的所有自定义类的对象 # class Course: # def __init__(self,name,price,period): # self.name = name # self.price = price # self.period = period # class Student: # def __init__(self,name,price,period): # self.name = name # self.price = price # self.period = period # python = Course('python',19800,'6 months') # linux = Course('python',19800,'6 months') # with open('courses','wb') as f: # pickle.dump(python,f) # with open('courses','rb') as f: # Course = pickle.load(f) # print(Course)
# 如果load一个对象,那么这个对象所对应的类必须已经在内存中
# 同一个类的对象 会存储在同一个文件中
(2)
# 面向对象的三大特性
# 继承
# 多态
# 封装
# 所有的面向对象的语言 三大特性 通用的
# 猫类 : 名字,品种,吃饭\喝水\叫(喵喵)\会爬树的 # 狗类 : 名字,品种,吃饭\喝水\叫(旺旺)\看家的 # class Cat: # def __init__(self,name,kind): # self.name = name # self.kind = kind # def eat(self): # print('%s is eating'%self.name) # def drink(self): # print('%s is drinking'%self.name) # def yell(self): # print('%s is yelling'%self.name) # def climb(self): # print('%s can climb'%self.name) # # class Dog: # def __init__(self,name,kind): # self.name = name # self.kind = kind # def eat(self): # print('%s is eating'%self.name) # def drink(self): # print('%s is drinking'%self.name) # def yell(self): # print('%s say miaomiao'%self.name) # def lookafter_door(self): # print('%s can look after door'%self.name)
# 继承 : 就是为了解决类与类之间代码重复的问题的 # 类的继承的语法: # 单继承 # class A:pass # class B(A):pass # print(B.__bases__) # 在定义类的时候加(),括号写的类就是继承的类 # B类继承A类 # A类 : 父类 基类 超类 # B类 : 子类 派生类 # 多继承(python支持 java不支持) # class C:pass # class D:pass # class E(C,D):pass # print(E.__bases__) # E继承C,D # C,D都是父类 # E是子类
# 子类可以继承父类的方法和属性 # 实例化的执行流程: # 先开辟一块空间,并且空间中已经有了一个类指针,指向Cat # 执行__init__方法,在Cat类的空间中没有init方法,找Animal类中的init # 将空间返回给小花变量 # 继承 # 子类调用方法,如果子类自己有用自己的,用了自己的就不用父类的了 # 如果子类自己没有才调用父类的
# 继承 # 子类调用方法,如果子类自己有用自己的,用了自己的就不用父类的了 # 如果子类自己没有才调用父类的 # 如果子类有个性化的父类没有的方法,可以单独定义在子类中 - 派生方法 # 只有子类能够使用父类中的方法,父类不可以使用子类中的方法
# class Animal: # def __init__(self,name,kind,language): # self.name = name # self.kind = kind # self.language = language # def eat(self): # print('%s is eating'%self.name) # def drink(self): # print('%s is drinking'%self.name) # def yell(self): # print('%s say %s'%(self.name,self.language)) # def sleep(self): # print('%s 在睡觉'%self.name) # class Cat(Animal): # def climb(self): # 派生方法 # print('%s can climb'%self.name) # def sleep(self): # #1. Animal.sleep(self) # 父类名,主动传self # # super(self,Cat).sleep() # 过程 super(self,子类名).方法名() # #2. super().sleep() # super().方法名() # print('团着睡') # class Dog(Animal): # 派生方法 # def lookafter_door(self): # print('%s can look after door'%self.name) # # 小花 = Cat('小花','金吉拉','喵喵') # 小花.sleep() # 既希望走父类的基础的sleep,又希望走自己的方法
当某一个方法,父类和子类都拥有的时候,那么在子类的方法中,调用父类的同名方法
# 1.父类名.方法名(self,...)
# 2.super().sleep(...)
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__)
# 继承 # 两种语法: # 单继承 # 多继承 # 几个基础概念 # 父类 : 超类 基类 # 子类 : 派生类 # 为什么要继承 : 几个类之间有重复的属性/方法 ,就把相同的属性和方法抽象出来,作为父类,子类去继承父类 # 父类和子类之间的关系 : 子类关联父类,父类并不关联子类 # 子类使用父类的方法 # 子类中有,父类中没有 : 用子类的 # 父类中有,子类中没有 : 用父类的 # 子类\父类中都有 : 默认情况下用子类的不用父类的 # 既想用父类又想用子类 : 父类名.方法名(子类对象),super().方法名() # 子类\父类中都没有 : 报错