python-继承-派生-字类访问父类方法-属性查找顺序-经典类与新式类-覆盖

一、继承

  1. 什么是继承:继承是一种关系,必须存在两个对象才能产生这个种关系,被继承的称为父,继承的一方成为子。在程序中继承指的是类与类之间的关系
  2. 为什么要使用继承:在生活中通过继承,子可以直接享受父提供内容。在程序中,通过继承可以直接使用父类已有的代码
  3. 如何使用:在子类中加上括号,加上父类的名称即可,在python中一个子类可以有多个父类,多个父类在括号中用逗号隔开
class parent:
    year = 2018
    def coding(self):
        print('正在编程')
    pass
class sub(parent):
    pass

print(parent.year)
print(sub.year)

s = sub()
#子类可以使用父类中的属性
print(s.year) #2018
#子类也可以用父类中的函数
s.coding() #正在编程
class Person:
    def __init__(self ,name ,age ,sex):
        self.name = name
        self.age = age
        self.sex = sex

    def eat(self):
        print("正在吃饭....")

    def study(self):
        print("正在学习....")

class Teacher(Person):

    def teaching(self):
        print("老师正在上课......")

t1 = Teacher("blex" ,30 ,"woman")
t1.eat() #正在吃饭....
t1.study() #正在学习....


class Student(Person):
    pass

stu1 = Student("张三" ,20 ,"man")
stu1.eat() #正在吃饭....
stu1.study() #正在学习....
#通过继承避免了重复代码的编写
#通过抽象,避免了继承到一些不应该有的内容
#应该先抽象再继承,在抽取过程中,可能会一些跟业务需求无关的类,这是正常的这些称之为公共父类
#公共父类的作用是存储多个子类相同属性的技能

二、派生

  1. 什么是派生:派生指的是子类继承某个父类,并且拥有自己独特的属性或技能。该子类称之为派生类
class Person:
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

    def sayHI(self):
        print("hello 我是%s 今年%s岁 性别:%s" % (self.name,self.age,self.sex))

class Student(Person):
    def __init__(self,name,age,sex,number):
        self.name = name
        self.age = age
        self.sex = sex
        self.number = number

    # 上课
    def attend_class(self):
        print("%s 正在上课.....")


stu1 = Student('张三',19,'男','1')
print(stu1.number)

三、子类访问父类方法

方法1:

class Person:
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex
        print(self)

    def sayHI(self):
        print("hello 我是%s 今年%s岁 性别:%s" % (self.name,self.age,self.sex))

class Student(Person):
    def __init__(self,name,age,sex,number):
        Person.__init__(self,name,age,sex)
        self.number = number

    def attend_class(self):
        print('%s 正在上课'%(self.name))

    def sayHI(self):
        #指名道姓
        #Person.sayHI(self)
        super().sayHI()
        print("学号:", self.number)

stu1 = Student("阿三",20,"woman","9527")
stu1.sayHI() #hello 我是阿三 今年20岁 性别:woman 学号: 9527

方法2:

class Person:
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex
        print(self)

    def sayHI(self):
        print("hello 我是%s 今年%s岁 性别:%s" % (self.name,self.age,self.sex))

class Student(Person):
    def __init__(self,name,age,sex,number):
        self.number = number

        # super() # 表示创建一个特殊的对象 用于调用父类的方法
        super().__init__(name,age,sex)
        # 了解:在python2中 super的使用方式有所不同 需要传入当前类,当前对象
        #super(Student,self).__init__(name,age,sex)

    # 上课
    def attend_class(self):
       print('%s 正在上课'%(self.name))

stu1 = Student("阿三",20,"woman","9527")
print(stu1.name,stu1.age,stu1.sex,stu1.number) #阿三 20 woman 9527

四、存在继承关系后的属性查找顺序

class S:
    age = 17

    def f1(self):
        print("S f1")

class A(S):
    pass

class B(A):
    pass
b = B()
print(b.age) #17

总结:

查找顺序:对象==>类==>父类

优先查找对象,如果对象没有则找类,如果类没有,会沿着继承关系一直找到最顶层的父类

无论是属性还是方法,查找顺序是一样的

五 、存在多个父类时的查找顺序

class E:
    a = 5

class A(E):
    a = 4
    pass

class B:
    a = 3
    pass

class C:
    a = 2
    pass

class D(A,B,C):
    # a = 1
    pass

d1 = D()
print(d1.a) 
#按照继承的顺序,先继承谁就先找谁
class S:
    a = 100

class A(S):
    # a = 1
    pass
class B(S):
    # a = 2
    pass
class C(S):
    # a = 3
    pass
class D(A):
    # a = 4
    pass
class E(B):
    # a = 5
    pass
class F(C):
    # a = 6
    pass
class G(D,E,F):
    pass

g1 = G()
print(g1.a)
#显示属性的查找顺序列表
print(G.mro()) #[<class '__main__.G'>, <class '__main__.D'>, <class '__main__.A'>, <class '__main__.E'>, <class '__main__.B'>, <class '__main__.F'>, <class '__main__.C'>, <class '__main__.S'>, <class 'object'>]

"""
s
a,b,c
d,e,f
g
"""

六、经典类型与新式类

  1. 什么是新式类:所有直接继承或间接继承object的类都是新式类,object 称之为根类 意思是所有类都源自于object类

  2. 为什么这么设计?例如:创建对象时,需要申请内存空间,创建新的名称空间,将对象的属性放入名称空间,这些复杂的基础操作都有Object来完成,所有的类都属于新式类(在python3中)

    在python3中默认所有类都是新式类

    而python2中默认是经典类(不会自动继承Object)

class S:
    pass
class Student(S):
    pass

#__bases__ 用于查看父类
print(Student.__bases__)  #(<class '__main__.S'>,)

#显示属性的查找顺序列表,属性查找属性就是按照该列表来查找的
print(Student.mro())

七、super获取父类内容时按照mro列表查找

class S:
    def f1(self):
        print("s f1")

class A(S):
    pass

class B(S):
    def f1(self):
        print("b f1")
    pass

class C(A,B):
    def f2(self):
        print("c f2")
        super().f1()


print(C.mro()) #[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.S'>, <class 'object'>]
c1 = C()
c1.f2()

总结:super访问父类内容时,按照mro列表属性查找

八、覆盖

class A:
    age = 18

    def f1(self):
        print("A f1")
    pass
class B(A):
    age = 19
    def f1(self):
        print("B f1")

b1 = B()
print(b1.age) #19
b1.f1() #B f1

总结:

子类出现了与父类重复的名字 称之为覆盖

子类出现了与父类不同的名字 称之为拍派生

小练习:

"""
    设计王者荣耀中的英雄类,每个英雄对象可以对其他英雄对象使用技能
    具备以下属性
    英雄名称,等级,血量
    和Q_hurt,W_hurt,E_hurt 三个属性,表示各技能的伤害量
    具备以下技能
    Q W E
    三个技能都需要一个敌方英雄作为参数,当敌方血量小于等于0时输出角色死亡
    
"""
class Hero:

    def __init__(self,name,level,hp,Q_hurt,W_hurt,E_hurt):
        self.name = name
        self.level = level
        self.hp = hp
        self.Q_hurt = Q_hurt
        self.W_hurt = W_hurt
        self.E_hurt = E_hurt

    def Q(self,enemy):

        enemy.hp -= self.Q_hurt
        print("%s 对%s 释放了 %s 技能" % (self.name,enemy.name,"Q"))
        print("造成了%s点伤害,剩余血量%s" % (self.Q_hurt, enemy.hp))
        if enemy.hp <= 0:
            print("%s被%s弄死了" % (enemy.name,self.name))

    def W(self,enemy):
        enemy.hp -= self.W_hurt
        print("%s 对%s 释放了 %s 技能" % (self.name, enemy.name, "W"))
        print("造成了%s点伤害,剩余血量%s" % (self.W_hurt,enemy.hp))
        if enemy.hp <= 0:
            print("%s被%s弄死了" % (enemy.name, self.name))

    def E(self,enemy):
        enemy.hp -= self.E_hurt
        print("%s 对%s 释放了 %s 技能" % (self.name, enemy.name, "E"))
        print("造成了%s点伤害,剩余血量%s" % (self.E_hurt, enemy.hp))
        if enemy.hp <= 0:
            print("%s被%s弄死了" % (enemy.name, self.name))

# 创建两个英雄
hero1 = Hero("小妲己",15,2000,50,500,600)
hero2 = Hero("小鲁班",15,1500,50,500,600)

hero1.Q(hero2)
hero1.W(hero2)
hero1.E(hero2)
hero1.E(hero2)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值