'''
#组合:自定义类的对象作为另外一个类的属性
class Teacher:
def __init__(self,name,age):
self.name=name
self.age=age
t1=Teacher('owen',18)
# print(type(t1.name),type(t1.age))
# print(t1.name)
# print(t1.name)
# print(t1.__dict__)
class Student:
#学生可以有老师的属性,学生的老师是谁
def __init__(self,name,age,teacher):#括号里面的只是参数接受实参传值
self.name=name#第一个name是自己定义的属性名,第二个是接受传进来的参数
self.age=age
#自定义类的对象作为类的属性:组合
self.teacher=teacher
#创建学生
stu=Student('mcc',18,t1)#将第一个类的对象当作参数传进来
print(stu.__dict__)
print(type(stu.name),type(stu.age),type(stu.teacher))
print(stu.name)
print(stu.teacher.age)
print(stu.teacher.name)
#上面两个共有属性是name,age
#组合就是可以将一个类的对象当作参数传递给另一个类,另一个类就可以访问这个对象的所有信息
class Wife:
def __init__(self,name,age):
self.name=name
self.age=age
# self.sex=sex
t2=Wife('hali',22)
t3=Wife('yali',23)
class Husband:#
def __init__(self,name,age,wife):
self.name=name
self.age=age
self.wife=wife
h1=Husband('zzz',26,t2)
h2=Husband('www',29,t3)
print(h1.wife)#<__main__.Wife object at 0x000001F59EADD7F0>
print(h2.wife)#<__main__.Wife object at 0x000001F59EADD828>
print(h1.wife.age)#22
print(h2.wife.name)#yali
#继承:派生:先产生父类,有父类派生出来的一个一个子类
#抽离:先诞生一个一个的子类,然后将子类具有的共性抽离,抽离成为一个父类
#优点:减少了重复的代码
class People:
def __init__(self,name):
self.name=name
def eat(self):
print(self.name+'在吃饭')
class Student(People):
identify='学生'
# def __init__(self,name):
# self.name=name
# def eat(self):
# print(self.name+'在吃饭')
s1=Student('Bob')
s1.eat()
class Teacher(People):
identify='老师'
# def __init__(self,name):
# self.name=name
# def eat(self):
# print(self.name+'去吃饭了')
t1=Teacher('owen')
t1.eat()
#所有的父类都具有子类共有的属性或者某些技能,将这些东西统一放到一起会减少代码重复
class Leader(People):
pass
l1=Leader('lxx')
l1.eat()
class Dog(People):
pass
d1=Dog('二哈')
d1.eat()
class Wuzhong:
identify='物种'
def __init__(self,name):
self.name=name
def eat(self):
print(self.name+'去吃饭')
class People(Wuzhong):
identify = '是嗯哼'
def eat(self):
print(self.name+'不 你是啊哈')
p1=People('enhen')
class Dog(Wuzhong):
pass
d1=Dog('二哈')
class Fish(Wuzhong):
pass
f1=Fish('金鱼')
print(p1.name)
p1.eat()
print(p1.identify)
print(d1.name)
print(d1.identify)
print(f1.name)
print(f1.identify)
#父类就是定义一个大类,里面的功能都是共有的,只需要定义一次
#封装与接口
class Sup:
__num=10
def __init__(self,name):
self.__name=name
# def name(self):#对象方法
# print(self)#是Sup的地址
# return self.__name
# s1=Sup()
# print(s1._Sup__num)# 10 封装实际上是将被封装的对象变成了_类名__名字,如果知道了封装原则,那么就可以访问到被封装的内容,不是绝对安全的封装
@property#将一个函数变成了一个属性,直接通过.名字访问
def name(self):
print(self)#<__main__.Sup object at 0x00000207E52EF9B0>
return self.__name#返回的名字要和init中封装的名字一致
# s1=Sup('owen')
# print(s1.name)#owen
# print(s1.name())#通过.名字()就会报错
@name.setter
def name(self,val):
self.__name=val
# s1=Sup('owen')
# s1.name='egon'
# print(s1.name)
# print(s1.name())#这个也是直接将函数变成了属性,不需要通过.名字()访问
@name.deleter#如果不定义这个,外界不可以删除,就会报错
def name(self):
del self.__name
# print('douniwan')
s1=Sup('owen')
print(s1.__dict__)
s1.name='mmm'
print(s1.name)
print(s1.__dict__)
del s1.name#如果要删除,外界就得进行这一步操作,所以是给自己留后路
#就是外界要删除
print(s1.__dict__)
# @classmethod#只装饰一次
# def eat(cls):
# print('quchifanba')
# print(Sup.__dict__)
# Sup.eat()
# def __c_fn(cls):
# return cls,'c fn'
# def o_fn(self):
# print(self.name,'o fn')
# print(Sup._Sup__c_fn())#要通过.名字()来访问
# s2=Sup('sh')
# s2.o_fn()#对象调用对象的方法,可以直接调用
# Sup.o_fn(s2)#类来调用里面的对象方法,得将对象当作参数传递进去
class Sup:
__num=10
def __init__(self,name):#对象方法的名称空间
self.__name=name
@property#给外界提供接口访问封装后的值
def name(self):
print(self)
return self.__name
@classmethod#类方法的调用
def __c_fn(cls):
print(cls,'c fn')
def __o_fn(self):
print(self.name,'o fn')
class Sub(Sup):#父类与子类
def test(self):
print(self)
print(self.__name)
# pass
print(Sub.name)
sub=Sub('sssss')
print(sub.name)
sub.test()
#继承关系
'''
'''
1.父类的所有未封装的 属性和方法,子类都能访问
2.父类的所有封装的属性和方法,子类都不能访问
--在外界通过子类或子类对象,不能访问
--在子类内部也不能访问
'''
'''
有继承关系下的属性的查找顺序
1 自身-父类-元类-报错
2 抽离:先写子类,抽离共有属性变成父类
派生:先写父类,派生出子类
'''
'''
#子类属性的查找顺序
class Sup:
num=10
def test(self):
print('test sup')
class Sub(Sup):
pass
# num=100
# def test(self):
# print('test sub')
print(Sub.num) #100 |10自身没有就去找父类
Sub().test()#test sub 优先自身,自身没有再去找父类
#test sup 自身没有就去查找父类的
'''
'''
#继承父类方法的重写
class Sup:#父类
def test(self):#父类的方法
print('>>>sup',self)
print('test sup')
class Sub(Sup):#子类
pass
#重用:还需要父类方法的功能,在父类方法功能基础上添加新功能
#突破点:在子类方法中取调用父类的方法,还有保证调用者是子类/子类对象
def test(self):
super().test()#这步就是调用父类的方法
print('>>>>sub',self)#为自己添加新功能
print('test sub')
Sub().test()
'''
'''
#init和super结合使用(当要使用父类方法时就super)
#人类:只需要初始化————name
#老师:需要初始化——name ,salary
#学生:需要初始化-name,grade
class People:
def __init__(self,name):#类的名称空间
self.name=name
def test(self):#类中的对象方法
print('people llla')#2
pass
class Teacher(People):
def __init__(self,name,salary):
super().__init__(name)
self.salary=salary
print(salary)
def test(self):
super().test()
print('teacher www')
pass
class Student(People):
def test(self):
super().test()
print('student lll')#3
def __init__(self,name,grade):
super().__init__(name)
self.grade=grade
print(grade) #1
Student('owen',98).test()
Teacher('egon',34).test()
Student().test()#使用父类不带参的不可以,必须要带参
#结果原因是走debug:1.student('owen',98).test() 2.super().__init__(name)进入父类
#3.父类中self.name=name 4.返回子类中的super 5.打印成绩 6.回到1 7.进入子类test,然后父类test
#8.打印people llla 9.返回到子类test,打印studentlll
#98
# people llla
# student lll
'''
'''
#多继承和单继承
#单继承:属性查找顺序优先自身,如果没有,再去找父类
#简单的多继承
# 子类名.mro()chao
class A:
name='A'
num=10
class B:
name='B'
count=100
#子类可以继承所有父类的所有可继承属性
class c(A,B):
# name='C'
count=30
pass
print(c.name) #C
print(c.count)#30
print(c.name)#A 先继承谁就先找谁的东西
print(c.mro())#c-A-B
#阶乘
def fn(num):
if num==1:
return num
return fn(num-1)*num
print(fn(4))
'''
'''
复杂的多继承
经典类:python2中才有,没有继承任何类的类
新式类:python2中直接或者间接继承object的类,python3中所有类都是新式类
'''
#先广后深新式类 先深后广经典类