欢迎来到 Kong Xiangqun 的博客

day22.继承及魔术方法__init__

一、单继承

"""
如果一个类继承另外一个类,
该类叫做子类(衍生类),被继承的类叫做父类(基类,超类)

继承: (1) 单继承 (2) 多继承
python中,所有的类都默认继承父类object
"""
 
class Human(object):
    hair = "黑色"
    sex = ""
    
    def cry(self):
        print("人类在伤心的时候,会留下鳄鱼的眼泪")
        
    def eat(self):
        print("人类在远古时候,抓到猎物直接吃")

    def __makebaby(self):
        print("人类在发育到成熟的时候,会造人")

1、子父继承之后,子类可以调用父类的公有成员

class Man(Human):
    pass

obj = Man()
print(obj.hair)
obj.cry()
View Code

2、子父继承之后,子类不能调用父类的私有成员

class Woman(Human):
    def pub_func(self):
        self.__makebaby()

obj = Woman()
# obj.__makebaby() error
# obj.pub_func() error 
View Code

3、子父继承之后,子类可以改写父类中的方法

"""
子父继承之后
如果子类里面有该成员属性或者方法,优先调用自己的
如果没有该成员,调用父类中的成员
如果都没有,直接报错
"""
class Children(Human):
    sex = "女性"
    def cry(self):
        print("小孩只会哇哇哇的哭")

obj = Children()
obj.cry()
print(obj.__dict__)
print(Children.__dict__)

 

二、多继承

1、基本语法

class Father():
    property = "风流倜傥,一表人才,一枝梨花压海棠"
    def f_hobby(self):
        print("社会摇,蹦迪,吃喝嫖赌,大保健")

class Mother():
    property = "闭月羞花,倾国倾城,一枝红杏出墙来"
    def m_hobby(self):
        print("打麻将,打牌,喝酒抽烟烫头,跳广场舞")

class Daughter(Father,Mother):
    pass

# 实例化对象
obj = Daughter()
print(obj.property)
obj.m_hobby()

2、super用法

"""
(1)super本身是一个类 super()是一个对象 用于调用父类的绑定方法
(2)super() 只应用在绑定方法中,默认自动传递self对象 (前提:super所在作用域存在self)
(3)super用途: 解决复杂的多继承调用顺序    
"""
class Father():
    property = "风流倜傥,一表人才,一枝梨花压海棠"
    def f_hobby():
        print("社会摇,蹦迪,吃喝嫖赌,大保健")

class Mother():
    property = "闭月羞花,倾国倾城,一枝红杏出墙来"
    def m_hobby(self):
        print("打麻将,打牌,喝酒抽烟烫头,跳广场舞")

class Son(Father,Mother):
    property = "喜欢打游戏,wow,lol,dnf,泡泡堂,cf,dota,大话西游,跑跑卡丁车,吃鸡"        
    
    # 1.利用类来调用父类的成员
    def skill1(self):    
        Father.f_hobby()
        print(Mother.property)

    # 2.利用对象调用父类的成员
    def skill2(self):
        self.m_hobby()
        print(self.property)
        
    # 3.利用super调用父类的属性和方法
    """
        super()只调用父类的相关公有成员,不会调用自己的本类成员,父类没有直接报错.
        super()在调用父类方法时,只调用父类的绑定方法,默认传递参数是本类的对象self
    """
    def skill3(self):
        # print(super())
        print(super().property)
        super().m_hobby()
        # super().f_hobby() error

obj = Son() 
print("<===============>")
obj.skill1()
print("<===============>")
obj.skill2()        
print("<===============>")
obj.skill3()
super

 

"""
self 和 super()的区别
self    在调用成员时,先看看自己的类对象中是否存在该成员,如果有调用自己的,如果没有,调用父类的.如果都没有报错
super() 在调用成员时,只调用父类的相关成员(属性,绑定方法),永远不会调用自己的.如果父类没有,直接报错.
"""

 

三、菱形继承

"""
     Human
Man          Woman
    Children
"""
class OldWoman():
    pass

class Human():
    pty = 4
    def feelT(self):
        print("原始人类如果热了,脱皮1")
        print(self.pty)
        print("原始人类如果冷了,扒别人的皮2")
    
class Man(Human):
    # pty = 3
    def feelT(self):
        print("现代男人如果热了,脱衣服,脱裤子3")
        super().feelT()
        print("现代男人如果冷了,脱别人的衣服,脱别人的裤子4")
        
class Woman(Human):
    # pty = 2
    def feelT(self):
        print("现代女人如果热了,吹空调,吃雪糕5")
        super().feelT()
        print("现代女人如果冷了,喝热水,用暖宝宝6")
    
class Children(Man,Woman):
    # pty = 1
    def feelT(self):
        print("现代小孩如果热了,就哭,嗯哭7")
        super().feelT()
        print("现代小孩如果冷了,也要哭8")
        
obj = Children()
obj.feelT()

1、mro列表

# super用途的一个体现.解决复杂的多继承调用顺序关系
# 类.mro()  返回的是方法调用顺序列表,针对于多继承下的同名方法,按照顺序依次的进行调用
lst = Children.mro()
print(lst)
"""
[
<class '__main__.Children'>, 
<class '__main__.Man'>, 
<class '__main__.Woman'>, 
<class '__main__.Human'>, 
<class 'object'>
]

"""

2、issubclass 判断子父关系 (应用在类当中,判断子父关系)

"""只要在一条继承链上即可(有血缘关系)"""
res = issubclass(Children,Man)
print(res)
res = issubclass(Children,Woman)
print(res)
res = issubclass(Children,Human)
print(res)
res = issubclass(Children,(Human,Woman,Man,OldWoman))
print(res)
res = issubclass(Children,OldWoman)
print(res)

3、isinstance (应用在对象和类之间,判断类型)

"""只要在一条继承链上即可(有血缘关系)"""
res = isinstance(obj,Children)
print(res)
res = isinstance(obj,Human)
print(res)
res = isinstance(obj,(Human,Children,Woman))
print(res)
res = isinstance(obj,OldWoman)
print(res)

四、魔术方法 __init__(self)

'''
    触发时机:实例化对象,初始化的时候触发
    功能:为对象添加成员
    参数:参数不固定,至少一个self参数
    返回值:无
'''

1、基本语法

class MyClass():
    def __init__(self):
        print("初始化方法被触发")
        # 为当前对象self 添加成员 name
        self.name = "袁伟倬"
# 实例化对象 
obj = MyClass()
print(obj.name)

2、带有多个参数的构造方法

class MyClass():
    def __init__(self,name):    
        # self.成员名 = 参数
        self.name = name
# 实例化对象
obj = MyClass("kxq") # 在实例化对象时候,给构造方法传递参数
print(obj.name)

3、类可以是一个,对象可以是多个

"""一个类可以实例化多个不同的对象,而对象和对象之间彼此独立,但都可以使用类中的公有的成员"""
class Children():
    def __init__(self,name,skin):
        self.name = name
        self.skin = skin
        
    def cry(self):
        print("小孩一出生就哇哇哇的哭")
        
    def drink(self):
        print("小孩一下生就要喝奶奶")
    
    def __la(self):
        print("小孩拉粑粑是私有的")
        
    def pub_info(self):
        print("该对象的名字是{},该对象的肤色是{}".format(self.name,self.skin))
    
# 创建第一个小孩
afanda = Children("阿凡达","蓝色的")
afanda.pub_info()
afanda.cry()

# 创建第二个小孩
afanti = Children("阿凡提","黄色的")
afanti.pub_info()
afanti.drink()

# 创建第三个小孩
bao = Children("我滴宝强","绿色的")
bao.pub_info()
# bao.__la() # 无法在类外调用私有的成员

五、练习

# ### 1.完成下列功能:
    # 1.1创建一个人类Person,再类中创建3个成员属性
        # animal = '高级动物'
        # soul = '有灵魂'
        # language = '语言'
    # 1.2在类中定义三个方法,吃饭,睡觉,工作.
    # 1.3在此类中的__init__方法中,给对象封装5个属性: 国家 , 姓名 , 性别 , 年龄 , 身高.
    # 1.4实例化四个人类对象:
        # 第一个人类对象p1属性为:中国,alex,未知,42,175.
        # 第二个人类对象p2属性为:美国,武大,男,35,160.
        # 第三个人类对象p3属性为:你自己定义.
        # 第四个人类对象p4属性为:p1的国籍,p2的名字,p3的性别,p2的年龄,p3的身高.
    # 1.5 通过p1对象执行吃饭方法,方法里面打印:alex在吃饭.
    # 1.6 通过p2对象执行吃饭方法,方法里面打印:武大在吃饭.
    # 1.7 通过p3对象执行吃饭方法,方法里面打印:(p3对象自己的名字)在吃饭.
    # 1.8 通过p1对象找到类中成员属性animal
    # 1.9 通过p2对象找到类中成员属性soul
    # 2.0 通过p3对象找到类中成员属性language
class Person():
    animal = '高级动物'
    soul = '有灵魂'
    language = '语言'
    
    def __init__(self,country,name,sex,age,height):
        self.country = country
        self.name = name
        self.sex = sex
        self.age = age
        self.height = height
    
    def eat(self):
        print("{}在吃饭".format(self.name))
        
    def sleep():
        pass
        
    def work():
        pass
        
p1 =  Person("中国","alex","未知",42,175)
p2 =  Person("美国","武大","",35,160)
p3 =  Person("中文","宋云杰","",18,130)
p4 =  Person(p1.country,p2.name,p3.sex,p2.age,p3.height)

p1.eat()
p2.eat()
p3.eat()
print(p1.animal)
print(p2.soul)
print(p3.language)
View Code

 

# ### 2.通过自己创建类,实例化对象
    #通过调用对象当中的方法,在终端输出如下信息
    #小明,10岁,男,上山去砍柴
    #小明,10岁,男,开车去东北
    #小明,10岁,男,最爱大保健

    #老李,90岁,男,上山去砍柴
    #老李,90岁,男,开车去东北
    #老李,90岁,男,最爱大保健
class MyClass():
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

    def print_func(self):
        strvar = """
{who},{age},{sex},上山去砍柴
{who},{age},{sex},开车去东北
{who},{age},{sex},最爱大保健
        """
        print(strvar.format(who=self.name,age=self.age,sex=self.sex))

obj = MyClass("小明","10岁","")
obj.print_func()
View Code

 

# ### 3.模拟英雄联盟写一个游戏人物的类
    #要求:
    #(1) 创建一个 Game_role 的类.
    #(2) 构造方法中给对象封装 name,ad(攻击力),hp(血量).三个属性.
    #(3) 创建一个attack方法,此方法是实例化两个对象,互相攻击的功能:
    #例: 实例化一个对象 盖伦,ad为10, hp为100
    #实例化另个一个对象 剑豪 ad为20, hp为80
    #盖伦通过attack方法攻击剑豪,此方法要完成 '谁攻击谁,谁掉了多少血,  还剩多少血'的提示功能.
class Game_role():
    def __init__(self,name,ad,hp):
        self.name = name
        self.ad = ad
        self.hp = hp
    
    def attack(self,obj):
        print('{}攻击{},{}掉了{}血,  还剩{}血'.format(self.name,obj.name,obj.name,self.ad,obj.hp-self.ad))
    
gailun = Game_role("盖伦",10,100)
jianhao = Game_role("剑豪",20,80)
gailun.attack(jianhao)  # self -> gailun  obj -> jianhao
View Code

 

# ### 4.请定义一个圆形类,有计算周长和面积的两个方法 (圆的半径通过参数传递给初始化方法)
import math
class Circle():
    def __init__(self,r):
        self.r = r

    def zhouchang(self):
        return 2 * math.pi * self.r

    def mianji(self):
        return math.pi * pow(self.r,2)

obj = Circle(10)
print(obj.zhouchang())
print(obj.mianji())
View Code

 

# ### 5创建AB两个类,A类中有属性abc=5把A类的对象存储在B类对象的成员属性pty中,用B类对象调用出abc这个值.
class A():
    abc = 5
    
class B():
    def __init__(self,obj):
        self.pty = obj

obj1 = A()
obj2 = B(obj1)
print(obj2.pty)
print(obj2.pty.abc)
View Code

 

简答题:

# 1.类或对象是否能做字典的key   可以~    
# 2.简述python的私有成员是如何实现的  改名策略[_类+私有成员名]
# 3.私有成员能在类的外部使用么?能在子类中使用么?不行 不行

 

读程序写结果

# # 1.读程序写结果.(不执行)
class StarkConfig(object):
    def __init__(self,num):
        self.num = num
    def changelist(self,request):
        print(self.num,request)

class RoleConfig(StarkConfig):
    def changelist(self,request):
        print('666')

# 创建了一个列表,列表中有三个对象(实例)
config_obj_list = [StarkConfig(1),StarkConfig(2),RoleConfig(3)]
for item in config_obj_list:
    print(item.num) # 1 2 3

print("<====================>")
# 2.读程序写结果.(不执行)
class StarkConfig(object):
    def __init__(self,num):
        self.num = num
    def changelist(self,request):
        print(self.num,request)

class RoleConfig(StarkConfig):
    pass
    
# 创建了一个列表,列表中有三个对象(实例)
config_obj_list = [StarkConfig(1),StarkConfig(2),RoleConfig(3)]
for item in config_obj_list:
    item.changelist(168) # 1 168 2 168 3 168
print(config_obj_list[0].num) # 1


# 3.读程序写结果.(不执行)
print("<====================>")
class StarkConfig(object):
    def __init__(self,num):
        self.num = num
    def changelist(self,request):
        print(self.num,request)

class RoleConfig(StarkConfig):
    def changelist(self,request):
        print(666,self.num)

config_obj_list = [StarkConfig(1),StarkConfig(2),RoleConfig(3)]
for item in config_obj_list:
    item.changelist(168) # 1,168 | 2,168 |  666,3
    
    
# 4.读程序写结果.(不执行)
print("<====================>")
class StarkConfig(object):
    def __init__(self,num):
        self.num = num
    def changelist(self,request):
        print(self.num,request)
    def run(self):
        self.changelist(999)

class RoleConfig(StarkConfig):
    def changelist(self,request):
        print(666,self.num)
    
config_obj_list = [StarkConfig(1),StarkConfig(2),RoleConfig(3)]
config_obj_list[1].run()   #2 999
config_obj_list[2].run()   #666 3
    
    
# 5.读程序写结果.(不执行)
print("<====================>")
class StarkConfig(object):
    def __init__(self,num):
        self.num = num
    def changelist(self,request):
        print(self.num,request)
    def run(self):
        self.changelist(999)

class RoleConfig(StarkConfig):
    def changelist(self,request):
        print(666,self.num)

class AdminSite(object):
    def __init__(self):
        self._registry = {}
    def register(self,k,v):
        self._registry[k] = v

site = AdminSite()
print(len(site._registry))  # 0
site.register('range',666)  # self._registry[range] = 666
site.register('shilei',438) # self._registry[shilei] = 438
print(len(site._registry))  # 2

site.register('lyd',StarkConfig(19))# self._registry[lyd] = StarkConfig(19)
site.register('yjl',StarkConfig(20))# self._registry[yjl] = StarkConfig(20)
site.register('fgz',RoleConfig(33)) # self._registry[fgz] = RoleConfig(33)
print(len(site._registry))   # 5
print(site._registry)


# 6.读程序写结果.(不执行)
print("<====================>")
class StarkConfig():
    def __init__(self,num):
        self.num = num
    def changelist(self,request):
        print(self.num,request)
    def run(self):
        self.changelist(999)

class RoleConfig(StarkConfig):
    def changelist(self,request): # request = 5
        print(666,self.num,request)

class AdminSite():
    def __init__(self):
        self._registry = {}
    def register(self,k,v):
        self._registry[k] = v

site = AdminSite()
site.register('lyd',StarkConfig(19))
site.register('yjl',StarkConfig(20))
site.register('fgz',RoleConfig(33)) # num 33

for k,row in site._registry.items():
    row.changelist(5) # 19 5 | 20 5 | 666 33 5
for k,row in site._registry.items():
    row.run() # 19 , 999 | 20 , 999 | 666 33 999


# 7.读程序写结果.(不执行)
"""
在类中为当前对象添加了私有成员.
"""
print("<====================>")
class JustCounter:
    __secretCount = 0
    def count(self):
        print(self.__secretCount) # 1.获取类当中的私有成员 0 | 2. 获取的是对象中的私有成员 1
        self.__secretCount += 1 # self.__secretCount = self.__secretCount + 1 = 0 + 1 = 1 # 给对象中的私有成员赋值
        
    def count3():
        print(JustCounter.__secretCount)  # 0
        # JustCounter.__secretCount = JustCounter.__secretCount + 1 = 0 + 1 = 1
        JustCounter.__secretCount += 1
        print(JustCounter.__secretCount) # 1

class Bars(JustCounter):
    def count2(self):
        print(self.__secretCount)
        
"""
#  情况一
counter1 = JustCounter() 
counter1.count() # 0
counter1.count() # 1
JustCounter.count3()  # 0 1

#  情况二
counter2 = Bars()
counter2.count() # 0
counter2.count() # 1

#  情况三
# JustCounter.count3() # 0 1 
"""
View Code

 

 

# ### 小人射击
"""面向对象的核心思想: 把对象当做程序中的一个最小单元,让对象操作一切"""
"""
弹夹:
    属性: 子弹数量 bulletcount
    方法: 无
枪 :
    属性: 弹夹
    方法: 射击 shoot
人 :
    属性: 枪
    方法: (1) 射击 (2) 换子弹
"""
from package.bulletbox import BulletBox
from package.gun import Gun
from package.person import Person


# 先创建弹夹
danjia = BulletBox(20)
# 在创建一杆枪
ak47 = Gun(danjia)
# 在创造一个人
songyunjie = Person(ak47,"宋云杰")


# 小人射击
if __name__ == "__main__":
    # 射击
    songyunjie.fire(15)
    # 填充
    songyunjie.fillcount(10)
    # 在射击
    songyunjie.fire(150)
main main.py
# ### 弹夹类

class BulletBox():
    def __init__(self,bulletcount):
        self.bulletcount = bulletcount
弹夹 bulletbox.py
# ### 枪类

class Gun():
    def __init__(self,bulletbox):
        # 存放的是弹夹对象
        self.bulletbox = bulletbox
        
    def shoot(self,shootcount):
        if self.bulletbox.bulletcount < shootcount:
            print("对不起,请先填充子弹~")
        else:
            # 剩余的子弹 = 总的子弹数量 - 射击的数量
            self.bulletbox.bulletcount -= shootcount
            print("" * shootcount , "你射出了{}发,还剩下{}发".format(shootcount,self.bulletbox.bulletcount))
枪类 gun.py
# ### 人类
class Person():
    def __init__(self,gun,name):
        self.gun = gun
        self.name = "宋云杰"
        
    # 填充子弹
    def fillcount(self,fillnum):
        # 往弹夹里面赛子弹
        # self.枪对象 -> 弹夹对象 -> 弹夹数量属性
        self.gun.bulletbox.bulletcount += fillnum
    
    # 射击
    def fire(self,num):
        print("{}此刻正在野外射击~".format(self.name))
        # 枪对象.shoot
        self.gun.shoot(num)
        
人类 person.py

 

posted @ 2020-08-07 21:42  kongxiangqun20220317  阅读(159)  评论(0编辑  收藏  举报