L6-14 继承多态

Posted xiaoxiao-ya

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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.多态就是指,对于同一个事物,可以有同名的两个或者多个方法,
#  一起调用,得到不同的结果。

 

以上是关于L6-14 继承多态的主要内容,如果未能解决你的问题,请参考以下文章

java 代码片段

多态的作用

python小白的进阶——细说继承和多态(附代码)

封装,继承,多态

C++多态公有继承

面向对象--继承和多态