Day03-python面向对象继承和多态

一、继承

定义一个类时,需要使用另外一个类的方法或属性,就可以通过继承实现

object是Python的顶级类,创建类是会自动继承,就拥有object中的方法

  • 定义格式

# 类的定义 
# 旧式类定义 一般在定义单个类时使用
class 类名:
    name = None
    
    def func(self):
        pass
​
# 新式类定义   一般在继承时使用
class 类名(指定需要继承的类):
    name = None
    
    def func(self):
        pass
​
​
# 新式类定义
class A():
    name = '张三'
​
    def func(self):
        # pass 不做处理
        pass
# 旧式类
class B:
​
    age = 20
​
    def fucn(self):
        pass
​
​
print(A.name)
print(B.age)

1-1 单继承

一次继承一个类

(1)Father类有一个性别属性,默认为男,同时,Father跑步速度快;

(2)如果Son类也想要拥有这些属性和方法,该怎么做呢?

(3)执行程序,观察程序效果。

# 单继承  只继承一个类
class Father:
​
    gender = '男'
​
    def run(self):
        print('跑步很快')
​
​
​
# 子类继承父类获取父类中属性和方法
class Son(Father):
​
    # 定义子类的属性和方法
    age = 20
​
    def play(self):
        print('玩游戏')
​
        
# 创建子类对象
s = Son()
# 使用子类对象操作父类的属性和方法以及自己的属性和方法
print(s.gender)
print(s.age)
​
s.run()
s.play()

(1)从前,有个摊煎饼的老师傅[Master],在煎饼果子界摸爬滚打多年,研发了一套精湛的摊煎饼(flapjack)技术;

(2)渐渐地,老师傅老了,就想着把这套技术传授给他唯一的最得意的徒弟[Apprentice];

(3)试着通过初始化、无参、定义方法与单继承来模拟程序。

# 单继承的使用
class Master:
    name = '师父'
​
    def flapjack(self):
        print('摊鸡蛋煎饼')
​
​
​
class Apprentice(Master):
    # 子类继承后可以不定义属性和方法,直接使用父类的方法
    pass
​
​
a = Apprentice()
​
# 子类使用父类方法
a.flapjack()

1-2 多继承

继承多个类

(1)徒弟是个爱学习的好孩子,想学习更多的摊煎饼技术;

(2)于是,在百度搜索到黑马程序员学校[School],报班来培训学习如何摊煎饼;

(3)使用多继承形式模拟程序。

# 单继承的使用
class Master:
    name = '师父'
​
    def flapjack(self):
        print('摊鸡蛋煎饼')
​
​
class School:
​
    name = '学校'
​
    def flapjack(self):
        print('摊肉肠煎饼')
​
​
class Apprentice(Master,School):
    # 子类继承后可以不定义属性和方法,直接使用父类的方法
​
    pass
​
​
a = Apprentice()
​
# 子类使用父类方法
a.flapjack()
​
# 查看子类的继承父类顺序
print(Apprentice.__mro__)
​

(1)可以发现老师傅[Master]、培训学校[School]都有摊煎饼方法;

(2)在徒弟对象中调用摊煎饼方法,会执行哪个父类的方法呢?

调用第一个父类的方法,print(Apprentice.__mro__) # 查看类的继承执行顺序

(3)思考:当给父类培训学校[School]新增编程方法后,子类能调用方法吗?

多继承时,父类方法都能被继承,但是如果有相同方法名,则在执行方法时,会按照print(Apprentice.__mro__)显示的顺序查找方法执行

如果想要能后执行所有父类方法,则需要将函数名字进行修改,避免函数名冲突

# 单继承的使用
class Master:
    name = '师父'
​
    def master_flapjack(self):
        print('摊鸡蛋煎饼')
​
​
class School:
​
    name = '学校'
​
    def school_flapjack(self):
        print('摊肉肠煎饼')
​
​
class Apprentice(School,Master):
    # 子类继承后可以不定义属性和方法,直接使用父类的方法
​
    pass
​
a = Apprentice()
​
# 子类使用父类方法
a.master_flapjack()
a.school_flapjack()
​
# 查看子类的继承父类顺序
print(Apprentice.__mro__)
​

1-3 方法重写

子类中定义了和父类相同的方法,就是对父类方法的重写,在执行方法时,使用的是子类的逻辑代码

(1)徒弟非常认真学习,终于掌握了老师傅的技术;

(2)接着,自己潜心钻研出类独门配方的全新摊煎饼技术;

(3)使用方法重写对摊煎饼方法进行处理。

当对父类方法重写后,执行时只会执行子类的的方法逻辑,不会再执行父类方法中的逻辑

# 重写父类方法  子类继承父类后定义了一个和父类相同名字的方法
​
# 单继承的使用
class Master:
    name = '师父'
​
    def flapjack(self):
        print('摊鸡蛋煎饼')
​
​
class Apprentice(Master):
​
    # 子类中定义了自己方法,和父类方法名一样
    # 子类相当于重写了父类的方法,在执行时按照子类的逻辑执行
    def flapjack(self):
        print('摊手抓饼')
​
​
a = Apprentice()
a.flapjack()

子类重写父类方法,在调用时执行的子类的逻辑,还想调用父类方方法,需要借助super()方法实现


(1)徒弟在培训学校学习努力,不仅掌握了黑马摊煎饼配方、还创办了自己煎饼果子的品牌;[配方、品牌]

(2)配合着一起摊煎饼,做出了更加美味的煎饼果子;

(3)使用调用父类方法在__init__()和摊煎饼方法中处理。

# 重写父类方法  子类继承父类后定义了一个和父类相同名字的方法
​
# 单继承的使用
class Master:
    name = '师父'
​
    def flapjack(self):
        print('摊鸡蛋煎饼')
​
​
class Apprentice(Master):
​
    # 子类中定义了自己方法,和父类方法名一样
    # 子类相当于重写了父类的方法,在执行时按照子类的逻辑执行
    def flapjack(self):
        # 在子类中调用父类相同的方法  使用super()
        # 通过super可以获取父类对象
        print(super().name)
        print('摊手抓饼')
        super().flapjack()
​
​
a = Apprentice()
a.flapjack()

1-4 多层继承

(1)N年后,当初的徒弟也老了;

(2)因此,徒弟想要把"有自己品牌,也有黑马配方的煎饼果子"的所有技术传授给自己的小徒弟;

(3)请试着使用多层继承的方式完成案例。

# 多层继承
# 重写父类方法  子类继承父类后定义了一个和父类相同名字的方法
​
# 单继承的使用
class Master:
    name = '师父'
    def flapjack(self):
        print('摊鸡蛋煎饼')
​
​
class Apprentice(Master):
    name = '徒弟'
    def flapjack(self):
        print('摊手抓饼')
        super().flapjack()
​
​
​
class LittleApprentice(Apprentice):
    name = '小弟'
​
    def flapjack(self):
        print('蒸包子')
        super().flapjack()
        
​
# 创建对象
la = LittleApprentice()
la.flapjack()
​
print(LittleApprentice.__mro__)
​
# 多层继承
# 重写父类方法  子类继承父类后定义了一个和父类相同名字的方法
​
# 单继承的使用
class Master:
    name = '师父'
    def flapjack(self):
        print('摊鸡蛋煎饼')
​
class School:
​
    name = '学校'
​
    def school_flapjack(self):
        print('摊肉肠煎饼')
​
​
class Apprentice(Master,School):
    name = '徒弟'
    def flapjack(self):
        print('摊手抓饼')
        super().flapjack()
​
​
​
class LittleApprentice(Apprentice):
    name = '小弟'
​
    def flapjack(self):
        print('蒸包子')
        super().flapjack()
        
​
# 创建对象
la = LittleApprentice()
la.flapjack()
la.school_flapjack()
print(LittleApprentice.__mro__)
​

二、多态

多态指的是一类事物的多中形态

相同的方法,产生不同的执行结果

运算符 + * 的多态

int + int 加法计算

str + str 字符串拼接

list + list 列表的数据合并


在python中可以使用类实现一个多态效果

在python中使用重写的方式实现多态

(1)定义两个类:老师、车;

(2)定义老师类的属性:姓名,定义老师类的方法:开车、停车;

(3)定义车类的属性:类型,定义车类的方法:开启、停止;

(4)联系:老师开车,执行程序,观察效果;

# 多态
class Teacher:
​
    def __init__(self,name):
        self.name = name
​
    def run(self):
        print(f'{self.name}老师开车')
​
    def stop(self):
        print(f'{self.name}老师停车')
​
class Car:
​
    def __init__(self,type):
        self.type = type
​
    def start(self):
        print(f'{self.type}启动')
​
    def close(self):
        print(f'{self.type}熄火')
​
t = Teacher('张三')
c = Car('小汽车')
​
c.start()
t.run()
c.close()
t.stop()

使用继承方式,调整执行的方法

# 多态
class Teacher:
​
    def __init__(self,name):
        self.name = name
​
    def run(self):
        print(f'{self.name}老师开车')
​
    def stop(self):
        print(f'{self.name}老师停车')
​
class Car(Teacher):
​
    def __init__(self,type,name):
        super().__init__(name)
        self.type = type
​
    def start(self):
        print(f'{self.type}启动')
        super().run()
    def close(self):
        print(f'{self.type}熄火')
        super().stop()
​
​
c = Car('小汽车','张三')
​
c.start()
c.close()

(5)思考:老师有可能开小轿车、骑自行车、坐地铁等,该怎么改进程序呢?

使用子类的重写功能实现多态

多态实现的流程

1-定义一个父类,在父类中定义需要执行的业务方法,具体方法的逻辑不用实现,直接pass,由继承的子类实现

2-定义多个功能的子类继承父类,在子类中对父类方法重写,实现自己子类的逻辑

3-封装一个统一的函数处理方法,让开发人员调用该方法

# 多态
class Teacher:
​
    def __init__(self,name):
        self.name = name
​
    def run(self):
        pass
​
    def stop(self):
        pass
​
class Car(Teacher):
​
    def __init__(self,type,name):
        super().__init__(name)
        self.type = type
​
    def run(self):
        # 在多态实现时,子类继承父类并对父类方法进行重写
        print(f'{self.type}启动')
        print(f'{self.name}老师开车')
    def stop(self):
        print(f'{self.type}熄火')
        print(f'{self.name}老师停车')
​
class Metro(Teacher):
​
    def __init__(self,type,name):
        super().__init__(name)
        self.type = type
​
    def run(self):
        # 在多态实现时,子类继承父类并对父类方法进行重写
        print(f'{self.type}启动')
        print(f'{self.name}老师乘坐地铁')
        
    def stop(self):
        print(f'{self.type}到站')
        print(f'{self.name}老师下车')
​
​
# 单独封装一个行为函数
# 该函数就是对外提供一个函数接口,其他开发人员使用,就调用函数
def action(obj):
    # obj接收一个对象
    obj.run()
    obj.stop()
​
c = Car('越野车','张三')
action(c)
​
​
m = Metro('地铁1号线','李四')
action(m)
​

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值