HSP_12章 Python面向对象编程oop_多态

P128 多态问题的引出

  • 先看一个问题
    在这里插入图片描述

# 说明: 先试用传统的方式完成
class Food:
    name = None

    def __init__(self,name):
        self.name = name

class Fish(Food):
    # 特有的属性和方法
    pass

class Bone(Food):
    # 特有的属性和方法
    pass


class Animal:
    name = None

    def __init__(self,name):
        self.name = name

class Dog(Animal):
    # 特有的属性和方法
    pass

class Cat(Animal):
    # 特有的属性和方法
    pass


class Master:
    name = None

    def __init__(self, name):
        self.name = name

    def feed__cat(self,cat :Cat,fish :Fish):
        print(f"主人{self.name},给动物:{cat.name},喂的食物是{fish.name}")

    def feed__dog(self,dog :Dog,bone :Bone):
        print(f"主人{self.name},给动物:{dog.name},喂的食物是{bone.name}")

# 测试
master = Master("zoran")
cat = Cat("小花猫")
fish = Fish("黄花鱼")
dog = Dog("大黄狗")
bone = Bone("大棒骨")

master.feed__cat(cat,fish)
master.feed__dog(dog,bone)

  • 传统的方法带来的问题是什么? 如何解决
1)问题是:代码的复用性不高,而且不利于代码维护和功能扩展
2)解决方案:引出我们要讲解的多态

P129 多态细节和使用

1. 多态介绍&特别说明

在这里插入图片描述

#举例说明:一个父类,具有多个子类,不同的子类对象调用相同的方法,执行的时候产生不同的状态,就是多态
class Animal:
    def cry(self):
        pass

class Dog(Animal):
    # 特有的属性和方法
    pass

class Cat(Animal):
    # 特有的属性和方法
    def cry(self):
        print("小猫喵喵叫...")

class Dog(Animal):
    # 特有的属性和方法
    def cry(self):
        print("小狗汪汪叫...")

class Pig(Animal):
    # 特有的属性和方法
    def cry(self):
        print("小猪噜噜叫...")

#注意; 在Python 面向对象变成中,子类对象可以传递给父类对象
def func(animal: Animal):
    animal.cry()

cat = Cat()
dog = Dog()
pig = Pig()

func(cat)
func(dog)
func(pig)


2. 多态的好处

在这里插入图片描述

3. 特别说明: Python多态的特点

1)Python中函数/方法的参数是没有类型限制的,所以多态在python中的体现并不是很严谨(比如:和java等强类型语言比)
2)Python并不要求严格的继承体系,关注的不是对象的类型本身,而是它是否具有要调用的方法(行为)

在这里插入图片描述

class AA:
    def hi(self):
        print("AA-hi()..")


class BB:
    def hi(self):
        print("BB-hi()...")


def test(obj):
    obj.hi()


aa = AA()
bb = BB()
test(aa)
test(bb)


4. 使用多态的机制来解决主人喂食物的问题

在这里插入图片描述

# 多态改进
class Food:
    name = None

    def __init__(self, name):
        self.name = name


class Fish(Food):
    # 特有的属性和方法
    pass


class Bone(Food):
    # 特有的属性和方法
    pass
class Grass(Food):
    # 特有的属性和方法
    pass

class Animal:
    name = None

    def __init__(self, name):
        self.name = name

class Dog(Animal):
    pass

class Cat(Animal):
    pass
class Horse(Animal):
    pass

class Master:
    name = None

    def __init__(self, name):
        self.name = name

    # 主人  给动物 喂食物
    def feed(self, animal: Animal, food: Food):
        print(f"主人{self.name},给动物:{animal.name},喂的食物是{food.name}")


# 测试
master = Master("Zoran")
cat = Cat("小花猫")
fish = Fish("黄花鱼")
dog = Dog("大黄狗")
bone = Bone("大棒骨")
horse = Horse("乌骓马")
grass = Grass("新鲜草")

master.feed(cat, fish)
master.feed(dog, bone)
master.feed(horse, grass)

P130 isinstance函数

  • 基本说明
    在这里插入图片描述


class AA:
    pass


class BB(AA):
    pass


class CC:
    pass


aa = AA()
bb = BB()
cc = CC()
print(f"obj是不是BB的对象{isinstance(bb, BB)}") #T
print(f"obj是不是AA的对象{isinstance(bb, AA)}") #T
print(f"obj是不是CC的对象{isinstance(bb, CC)}") #F

num = 9
print(f"num 是不是int: {isinstance(num, int)}") #T
print(f"num 是不是str: {isinstance(num, str)}") #F
# 是元组中的一个返回 True
print(f"num 是不是str/int/list: {isinstance(num, (int,str,list))}") #T



  • 多态练习题
class A:
    i = 10

    # self到底是A还是B[B]
    #当调用对象成员的时候,会和对象本身动态关联
    def sum(self):
        return self.getI() + 10

    def sum1(self):
        return self.i + 10

    def getI(self):
        return self.i


class B(A):
    i = 20

    # def sum(self):
    #     return self.i + 20

    def getI(self):
        return self.i

    # def sum1(self):
    #     return self.i + 10

# 创建B的对象
b = B()
print(b.sum())  # 输出什么? 40  30?
print(b.sum1()) #输出什么? 30  30?

在这里插入图片描述

class Employee:
    __name = None
    __salary = None

    def __init__(self, name, salary):
        self.__name = name
        self.__salary = salary

    def get_annual(self):
        return self.__salary * 12

    def set_name(self, name):
        self.__name = name

    def get_name(self):
        return self.__name

    def set_salary(self, salary):
        self.__salary = salary

    def get_salary(self):
        return self.__salary


class Manager(Employee):
    __bonus = None

    def __init__(self, name, salary, bonus):
        super().__init__(name, salary)
        self.__bonus = bonus

    def set_bonus(self, bonus):
        self.__bonus = bonus

    def get_bonus(self):
        return self.__bonus

    def manage(self):
        print(f"经理:{self.get_name()}正在工作中...")

    # 根据需要,重新manager的年工资方法
    def get_annual(self):
        # 调用父类的get_salary方法+ 奖金
        return super().get_annual() + self.__bonus


class Worker(Employee):

    def work(self):
        print(f"普通工人:{self.get_name()}正在工作中...")


def show_emp_annual(e: Employee):
    print(f"{e.get_name()},年工资是: {e.get_annual()}")


def working(e: Employee):
    # 如果是普通员工
    if isinstance(e, Worker):
        e.work()
    # 如果是经理
    elif isinstance(e, Manager):
        e.manage()
    else:
        print("无法确定工作状态")

# 测试
worker = Worker("king", 10000)
show_emp_annual(worker)

manager = Manager("tim", 20000, 100000)
show_emp_annual(manager)

working(worker)
working(manager)

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pigerr杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值