day11:面向对象:封装、继承、多态
# 定义一个类:包含一个:类属性,count,三个对象属性:name,age,address # count用来记录第几个学生,定义三个对象,然后为这三个对象分别赋值, # 把他们按照顺序写到文件里,格式如下: # 1:{'name':'张三','age':'18','address':'北京'} # 2:{'name':'张二','age':'28','address':'上海'} # 3:{'name':'张大','age':'38','address':'北京'} # 然后在读出来,给以上定义的变量,把地址前面,加上中国
class Student():
count=0
def __init__(self,name,age,address):
self.name=name
self.age=age
self.address=address
Student.count+=1
def pt(self):
print(self.name,self.age,self.address)
zs=Student("张三",14,"上海")
f=open("a.txt","w")
f.write(str(Student.count))
zd=dict(name=zs.name,age=zs.age,address=zs.address)
f.write(":")
f.write(str(zd))
f.write("\n")
ls=Student("李四",16,"河北")
f.write(str(Student.count))
zd=dict(name=ls.name,age=ls.age,address=ls.address)
f.write(":")
f.write(str(zd))
f.write("\n")
ww=Student("王五",20,"北京")
f.write(str(Student.count))
zd=dict(name=ww.name,age=ww.age,address=ww.address)
f.write(":")
f.write(str(zd))
f.write("\n")
f.close()
f=open("a.txt","r")
line=f.readline()#读一行例如 1:{'name':'张三','age':'18','address':'北京'}
obj=[]#定义一个列表,用来存放每一行的学生对象
while len(line)>0:
zd=eval(line[2:].strip('\n'))#如果此处是2:-1,那么最后一行没有\n的会被切掉最后一个字符导致数据不完整
print(zd)
x=Student(zd["name"],zd["age"],"中国"+zd["address"])
obj.append(x)
line=f.readline()
f.close()
for x in obj:
x.pt()
#继承
class People():
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def say(self):
print("我叫",self.name,"今年%d岁"%self.age,"性别",self.sex)
class Student(People):
def __init__(self,name,age,sex,score):#继承父类属性
super().__init__(name,age,sex)#super()代表父类
self.score=score
def talk(self):
print("我叫",self.name,"今年%d岁"%self.age,"考了%d分"%self.score)
zs=Student("张三",14,"男",99)
zs.say()#不仅可以继承父类的属性,也可以继承父类的方法
zs.talk()
print(zs.name)
class People(): def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def say(self): print("我叫",self.name,"今年%d岁"%self.age,"性别",self.sex) class Student(People): def talk(self): print("我叫",self.name,"今年%d岁"%self.age) zs=Student("张三",14,"男") zs.say() zs.talk() print(zs.name)
class People(): def __init__(self,name,age,sex,yan): self.name=name self.age=age self.sex=sex self.__yan=yan#加两个下划线表示这个属性是这个类的私有属性,不能被继承,只能在这个类中使用 def say(self): print("我叫",self.name,"今年%d岁"%self.age,"性别",self.sex,self.__yan) class Student(People): def __init__(self,name,age,sex,__yan,score):#继承父类属性 super().__init__(name,age,sex,__yan) self.score=score def talk(self): print("我叫",self.name,"今年%d岁"%self.age,"考了%d分"%self.score,"视力",self.__yan) zs=Student("张三",14,"男",2.0,99) zs.say()#子类使用父类的方法时可以使用父类的私有属性 zs.talk()#会报错,因为Student不能继承People的私有属性,子类的方法不能使用父类的私有属性 print(zs.name)
class Student(): def __init__(self,name,age,sex): self.name=name self.__age=age self.sex=sex def __sayage(self): print(self.__age,"岁") def say(self): self.__sayage() def sayage(self): print(self.__age, "岁") zs=Student("张三",14,"男") zs.sayage() zs.say()#可以通过Student的内部方法调用__sayage() #zs.__sayage()#会报错,因为无法直接从外部调用__sayage()方法
#多继承 class A(): def AA(self): print("AAAAAA") class B(): def BB(self): print("BBBBBB") class C(A,B):#C同时继承A和B def CC(self): print("CCCCCC") x=C() x.AA() x.BB() x.CC()
class A(): def AB(self): print("AA") class B(): def AB(self): print("BB") class C(A,B):#括号里A和B的顺序就是调用A和B的顺序,若A和B中的方法名相同,则调用前面的类中的方法 def CC(self): print("CC") class D(B,A): def DD(self): print("DD") class E(B,A): def AB(self):#覆盖(重载)了父类中的方法 print("EE") c=C() c.AB() d=D() d.AB() e=E() e.AB()
class People(): def say(self): print("开个玩笑") class Student(People): def say(self): super().say() print("呵呵") c=Student() c.say()
#菱形继承 class A(): def __init__(self): print("A开始") print("A结束") class B(A): def __init__(self): print("B开始") super().__init__() print("B结束") class C(A): def __init__(self): print("C开始") super().__init__() print("C结束") class D(B,C):#C是B的父类 def __init__(self): print("D开始") super().__init__() print("D结束") class E(C,B):#B是C的父类 def __init__(self): print("E开始") super().__init__() print("E结束") d=D() print(D.mro())#mro表:前面的是后面的子类,后面的是前面的父类 e=E() print(E.mro())
#多态 class Dog(): def jiao(self): print("旺旺") class Cat(): def jiao(self): print("喵喵") class Pig(): def jiao(self): print("哼哼") def jiao(o): o.jiao() d=Dog() c=Cat() p=Pig() jiao(d) jiao(c) jiao(p)
class A(): x=10 class B(A): pass class C(A): pass print(A.x) print(B.x) print(C.x) B.x=12 print(A.x) print(B.x) print(C.x)
class A(): __slots__ = ("name","age","sex","address")#限制属性,无法使用和添加这几种之外的属性 def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex zs=A("张三",12,"男") zs.address="河北" zs.eat="米饭"#会报错,因为__slots__中没有eat属性
class A(): def __init__(self): pass @property#修饰下面的方法,此符号修饰的函数当成属性使用 def name(self):#get 方法,(获取值) return self._name#返回和函数名字不一样的属性 @name.setter#name的设置方法,此属性可以用属性名=来启动此方法 def name(self,name_x):#set设置值 if name_x<30:#简单的赋值语句 self._name=30 else: self._name=name_x def aaa(self): self.name=22#此处启动了name.settet修饰的name方法 a=A() a.aaa() print(a.name)#此处启动了property修饰的name获取方法 #只要给self.name赋值,就会启动setter赋值语句,所以在setter中要使用和self.name不同的属性名来避免出现死循环,如self._name
class A(): def __init__(self): pass @property def data(self): return self._data @data.setter def data(self,dataday): # if len(dataday)<10: # self._data=dataday[:5]+"0"+dataday[5:] # else: # self._data=dataday if len(dataday)<10: ls=dataday.split("-") if len(ls[1])!=2 and len(ls[2])==2: self._data=ls[0]+"-0"+ls[1]+"-"+ls[2] elif len(ls[1])==2 and len(ls[2])!=2: self._data=ls[0]+"-"+ls[1]+"-0"+ls[2] elif len(ls[1])!=2 and len(ls[2])!=2: self._data=ls[0]+"-0"+ls[1]+"-0"+ls[2] else: self._data=dataday # def aaa(self): # self.data="2019-2-23" a=A() a.data="2019-9-3" # a.aaa() print(a.data)