• L6-14 继承多态


    一、课程导入

    上节课我们初步学习了面向对象编程的特点,我们可以将一些代码封装在一起,反复使用,这样提高了编写程序的效率。

    封装、继承和多态是面向对象编程的三大特征。

    学习了封装的强大功能, 你是不是很想了解继承 和多态的作用呢?

    二、继承

    1.什么是继承

      1.1 在现实的世界中

    人们可以从他们的父母那里继承一些东西,
    例如黑头发、黄皮肤或者继承一些财产之类的东西。

      1.2 在面向对象编程中

    一个类从其他的类那里继承属性和方法,这样就有了类的整个家族;
    在这个家族中,每个类共享相同的属性和方法。

    总结:

    1.继承是一种创建新类的方式
    
    2.新建的类可以创建一个或多个父类,父类有称为基类或者超类
    
    3.新建的类称为派生类或者子类
    
    在python中类的继承分为:单继承或多继承

    2. python中继承的特点:

    1. 子类可以遗传/重用父类的属性
    2. python中一个子类可以同时继承多个父类

    3.为何要用继承 

    减少类与类之间代码冗余

    4.如何用继承

    4.1 

    class ParentClass1: #定义父类
        pass
     
    class ParentClass2: #定义父类
        pass
     
    class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass
        pass
     
    class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类
        pass

     4.2 

    class Dog(): #定义一个父类Dog,类名后加上括号
        pass
    class Too(Dog):#将类名Dog放入子类Ted括号中
        pass
    class Loo(Dog):#将类名Dog放入子类Ted括号中
        pass
    
    # Dog是被继承的类,它是父类,Too和Loo是子类,可以从父类哪里继承一些属性和方法。
    # pass在此位置相当于占位的,如果不写东西会报错

    4.3 试一试

    class Dog:#定义一个父类
        def eat(self):
            print("吃点东西")
    class Too(Dog):#将父类的类名放入子类Too括号中
        def ok(self):
            print("好呀!")
    class Loo(Dog):#将父类的类名放入子类Loo括号中
        def yeah(self):
            print("嗯嗯!")
    lala=Too ()
    HaHa = Loo()
    lala.eat()
    lala.ok()
    HaHa.eat()
    HaHa.yeah()

     4.4 为父类添加基本上属性

    class Dog:#定义一个父类
        # 创建构造方法,增加name值
        def __init__(self,name):
            self.name=name
        def eat(self):
            print("吃点东西")
    class Too(Dog):#将父类的类名放入子类Too括号中
        def ok(self):
            print("好呀!")
    class Loo(Dog):#将父类的类名放入子类Loo括号中
        def yeah(self):
            print("嗯嗯!")
    lala=Too ("大黄") # 创建对象时需提供相对应的实参
    HaHa = Loo("旺财")
    lala.eat()
    lala.ok()
    HaHa.eat()
    HaHa.yeah()

    总结:在上述例子中,子类继承父类的属性和方法,在子类中定义了方法,那是否可以为子类增加属性呢?

    5.绑定类的初始化方法

    class Dog():
        def __init__(self,name):
            self.name = name
        def eat(self):
            print("吃点东西")
    class Too(Dog):
        def __init__(self,name,hair):
            Dog.__init__(self,name)
            self.hair = hair  # 给子类Too定义属性hair,Too类创建的对象都会有属性hair
        def ok(self):
            print("好呀!")
    lala=Too("大黄","黄色") # 传入两个参数
    lala.eat()
    lala.ok()
    # 如果要给予子类增加属性,应当显示调用父类的初始化方法,将父类与子类关联在一起。

     细讲:

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

    第一行代码,在子类__init__()方法中先写来自父类的属性name,后面添加上子类新的属性hair,

    第二行代码用来将父类和子类关联在一起,这样不用重写父类的属性变量self.name,

    子类Too实例化对象会包含父类的所有属性,

    第三行写上新的属性变量self.hair。 

    6.实例

    class Animal:      #父类  基类  超类
        def __init__(self,name,life_value,aggr):
            self.name= name
            self.life_value = life_value
            self.aggr = aggr  #攻击力
        def eat(self):
            self.life_value += 10  #谁调谁的血量就增加
    
    class Person(Animal):  #子类  派生类
        def __init__(self, money, name, life_value, aggr):
            super().__init__(name, life_value, aggr)
            self.money = money  #派生出来的一个属性
        def attack(self,enemy):    #人的派生方法
            #enemy.life_value = enemy.life_value - self.aggr
            enemy.life_value -= self.aggr
    
    class Dog(Animal): #子类  派生类
        def __init__(self,name,breed, life_value,aggr):
            # Animal.__init__(self,name,breed, life_value,aggr)#让子类执行父类的方法 就是父类名.方法名(参数),连self都得传
            super().__init__(name,life_value,aggr) #super关键字  ,都不用传self了,在新式类里的
            # super(Dog,self).__init__(name,life_value,aggr)  #上面super是简写
            self.breed = breed
        def bite(self,person):   #狗的派生方法
            person.life_value -= self.aggr
        def eat(self):  #父类方法的重写
            super().eat()
            print('dog is eating')
    
    # ha2 = Dog('旺财','哈士奇',20000,100)
    # egg = Person('egon',500,1000,50)
    # print(egg.aggr)
    # print(ha2.aggr)
    # egg.eat()
    # print(egg.life_value)
    #
    # egg.eat()
    # print(egg.life_value)
    #
    # ha2.eat()
    # print(ha2.life_value)
    #
    # print(egg.life_value)
    # ha2.bite(egg)
    # print(egg.life_value)
    #
    
    ha2 = Dog('牛头梗','旺财',20000,100)
    print(ha2.life_value)
    ha2.eat()  #如果父类有的方法子类里面也有,那么就叫做方法的重写,就不执行父类的了,去执行子类了
    print(ha2.life_value)
    
    
    super(Dog,ha2).eat() #生掉父类的方法,但是不推荐这样用
    print(ha2.life_value)
    
    #在继承中,如果子类有的方法就执行子类的
    # 如果子类没有的方法就执行父类的
    实现调用父类的方法

    三、多态

    1.什么是多态

    多态指的是一类事物有多种形态(比如:老师.下课铃响了(),
    学生.下课铃响了(),老师执行的是下班操作,学生执行的是放学操作,
    虽然二者消息一样,但是执行的效果不同)
    例如:动物有多种形态:人,狗,猪

    在面向对象编程时,对于同一个事物,可以有同名的两个或者多个方法,
    用一种调用方式,能够得到不同的结果,这就是多态。

    总结:多态指的是同一种/类事物的不同形态

    2.为何要用多态

    多态性:在多态的背景下,可以在不用考虑对象具体类型的前提下而直接使用对象
    多态性的精髓:统一

    3.如何用多态

     3.1

    # 父类
    class Animal:
        def speak(self):
            pass
    # 子类
    class People(Animal):
        def speak(self):
            print('say hello')
    # 子类
    class Dog(Animal):
        def speak(self):
            print('汪汪汪')
    # 子类
    class Pig(Animal):
        def speak(self):
            print('哼哼哼')
    
    # 产生三个对象
    p1=People()
    p2=Dog()
    p3=Pig()
    
    # 定义统一技能的接口
    def speak(animal):
        animal.speak()
    
    # 由于继承了父类,都具有speak方法
    speak(p1)
    speak(p2)
    speak(p3)

    3.2 假设要设计程序,计算不同形状的面积,比如三角 形,长方形,可以创建两个类,用一种方法调用。

    class Triangle:
        def __init__(self,width,height):
            self.width = width
            self.height = height
        def getArea(self):
            area = self.width*self.height / 2.0
            print(area)
    class Square:
        def __init__(self,size):
            self.size = size
        def getArea(self):
            area = self.size*self.size
            print(area)
    myTriangle = Triangle(4,5)
    mySquare = Square(10)
    myTriangle.getArea()
    mySquare.getArea()

    在计算两个形状的面积时,都 采用了getArea ()这个方法。

    四、动手实践

    大鱼吃小鱼是非常经 典的一款小游戏,现 在来模拟下,实现小 鱼和鲨鱼的几个动作。

    分析:

     代码:

    #1.利用学习过的随机模块,获得父类Fish的位置
    import random
    class Fish:
        def __init__(self):
            self.x = random.randint(0,50)
            self.y = random.randint(0,50)
        def move(self):
            print("我的位置是:",self.x,self.y)
    #2.暂时先不考虑金鱼的移动方向等问题
    class Goldfish(Fish):
        pass
    #获得父类的方法,定义一个eat方法
    class Shark(Fish):
        def __init__(self):
            Fish.__init__(self)
            self.hungry = True
        def eat(self):
            if self.hungry:
                print("吃货的梦想就是天天有吃的,哈哈")
                self.hungry = False
            else:
                print("太撑了,吃不下")
    #3.实例化小鱼goldfish和鲨鱼shark,并调用方法
    goldfish = Goldfish()
    goldfish.move()
    shark = Shark()
    shark.eat()
    shark.eat()
    shark.move()

    五、总结

    # 1.在面向对象编程中,一个类从其他的类那里继承属性和方法,
    #   这样就有了类的整个家族;在这个家族中,每个类共享相同的属性和方法。
    # 2.如果父类构造函数初始化了一些属性,子类不显式调用父类的构造方法,就会报错。
    # 3.多态就是指,对于同一个事物,可以有同名的两个或者多个方法,
    #  一起调用,得到不同的结果。
  • 相关阅读:
    面试题练习
    小作业7
    小作业6,7
    小作业
    坦克大战
    面试题
    20181213作业
    20181212作业
    20181211作业
    第三周周末作业
  • 原文地址:https://www.cnblogs.com/xiaoxiao-ya/p/11954475.html
Copyright © 2020-2023  润新知