【飞浆百度领航团零基础Python】学习笔记

文章目录

  • 一. 继承
  • 二. 方法重写
  • 三. 多态
  • 四. 多继承
  • 使用Athlete的方法

课程连接
https://aistudio.baidu.com/aistudio/course/introduce/7073

一. 继承

定义:class 子类名(父类名):
说明:(1)如果子类有新增属性,需要在子类__init__方法中,调用父类的__init__
(2)如果子类没有新增的属性,子类不需要写__init__方法

使用方式:对象名 = 子类名()
继承的好处:代码重用,升级功能(重写),新增功能(新的方法)
例:

数据文件loren.txt内容:loren,2011-11-3,270,3.59,4.11,3:11,3:23,4-10,3-23,4:10,4.21,4-21
# 取出loren.txt中的数据并进行粉刺处理
def get_coach_data(filename):
    with open(filename) as f:
        line = f.readline()
    return line.strip().split(',')
# 定义Athlete类
class Athlete:
    def __init__(self, a_name, a_dob = None, a_times = []):
        self.name = a_name
        self.dob = a_dob
        self.times = a_times
    def top3(self):
        return sorted(set([self.sanitize(t) for t in self.times]))[0: 3]
    def sanitize(self, time_string):
        if '-' in time_string:
            splitter = '-'
        elif ':' in time_string:
            splitter = ':'
        else:
            return (time_string)
        (mins, secs) = time_string.split(splitter)
        return (mins + '.' + secs)
# 定义橄榄球运动员类继承Athlete类
class Rugby(Athlete):
    def __init__(self, a_name, a_bod, a_squat, a_times):
        # 新增squat属性,调用父类__init__
        Athlete.__init__(self, a_name, a_bod, a_times)
        self.squat = a_squat  # 深蹲次数
    # 继承后下面两个函数就在Rugby类中,不用再写
    # def top3(self):
    #     return sorted(set([self.sanitize(t) for t in self.times]))[0: 3]
    # def sanitize(self, time_string):
    #     if '-' in time_string:
    #         splitter = '-'
    #     elif ':' in time_string:
    #         splitter = ':'
    #     else:
    #         return (time_string)
    #     (mins, secs) = time_string.split(splitter)
    #     return (mins + '.' + secs)
# 测试输出
loren = get_coach_data('./loren.txt')
rugby = Rugby(loren.pop(0), loren.pop(0), loren.pop(0), loren)
print('姓名:%s, 生日:%s, 深蹲:%s个, 最快的3次成绩:%s' %(rugby.name, rugby.dob, rugby.squat, rugby.top3()))
# 输出结果:姓名:loren, 生日:2011-11-3, 深蹲:270个, 最快的3次成绩:['3.11', '3.23', '4.10']

二. 方法重写

子类方法与父类方法完全相同,子类若重写了父类的方法,则子类对象调用方法时就是调用的自己类中重新的方法。
例:

# 修改top3方法,取出最慢的三次记录,可以重复
class Rugby(Athlete):
    def __init__(self, a_name, a_bod, a_squat, a_times):
        Athlete.__init__(self, a_name, a_bod, a_times)
        self.squat = a_squat
    def top3(self):
        return sorted([self.sanitize(t) for t in self.times])[-3: ]
# 测试输出
loren = get_coach_data('./loren.txt')
rugby = Rugby(loren.pop(0), loren.pop(0), loren.pop(0), loren)
print('姓名:%s, 生日:%s, 深蹲:%s个, 最慢的3次成绩:%s' %(rugby.name, rugby.dob, rugby.squat, rugby.top3()))
# 输出结果:姓名:loren, 生日:2011-11-3, 深蹲:270个, 最慢的3次成绩:['4.11', '4.21', '4.21']

三. 多态

多态性:一个事物多种形态
多态的好处:减少重复代码,分离经常改变的代码与不经常改变的代码,使得代码可维护性提高。
例:
有多种运动员,它们的top3完全不同,我们需要为每种运动员定义一个子类,调用会是一堆重复的代码。

# 定义其它种类运动员继承Athlete类,取出最快的3次记录,可以重复
class OtherAthlete(Athlete):
    def __init__(self, a_name, a_bod, a_squat, a_times):
        Athlete.__init__(self, a_name, a_bod, a_times)
        self.squat = a_squat
    def top3(self):
        return sorted([self.sanitize(t) for t in self.times])[0: 3]
# 有多种运动员,为每种运动员定义一个子类,调用会是一堆重复的代码
mark1 = get_coach_data('./mark.txt')
mark2 = get_coach_data('./mark1.txt')
mark3 = get_coach_data('./mark2.txt')

mark1 = OtherAthlete(mark1.pop(0), mark1.pop(0), mark1.pop(0), mark1)
mark2 = OtherAthlete(mark2.pop(0), mark2.pop(0), mark2.pop(0), mark2)
mark3 = OtherAthlete(mark3.pop(0), mark3.pop(0), mark3.pop(0), mark3)

print('姓名:%s, 生日:%s, 深蹲:%s个, 最快的3次成绩:%s' %(mark1.name, mark1.dob, mark1.squat, mark1.top3()))
print('姓名:%s, 生日:%s, 深蹲:%s个, 最快的3次成绩:%s' %(mark2.name, mark2.dob, mark2.squat, mark2.top3()))
print('姓名:%s, 生日:%s, 深蹲:%s个, 最快的3次成绩:%s' %(mark3.name, mark3.dob, mark3.squat, mark3.top3()))

# 运行结果
# 姓名:mark,生日:2010-2-4,深蹲:300个,最快的3次成绩:['3.11', '3.11', '3.23']
# 姓名:mark,生日:2010-2-4,深蹲:111个,最快的3次成绩:['3.11', '3.11', '3.23']
# 姓名:mark,生日:2010-2-4,深蹲:222个,最快的3次成绩:['3.11', '3.11', '3.23']
# 有多种运动员,为每种运动员定义一个子类,调用会是一堆重复的代码
loren = get_coach_data('./loren.txt')
mark = get_coach_data('./mark.txt')

loren = Rugby(loren.pop(0), loren.pop(0), loren.pop(0), loren)
mark = OtherAthlete(mark.pop(0), mark.pop(0), mark.pop(0), mark)

print(loren.name)
print(loren.dob)
print(loren.squat)
print(loren.top3())

print(mark.name)
print(mark.dob)
print(mark.squat)
print(mark.top3())

# 运行结果
# loren
# 2011-11-3
# 270
# ['4.11', '4.21', '4.21']
# mark
# 2010-2-4
# 300
# ['3.11', '3.11', '3.23']

下面是使用多态的代码:

# print_rugby()的参数athlete,athlete.name,athlete.top3()的行为由athlete的子类决定。
loren = get_coach_data('mywork/loren.txt')
mark = get_coach_data('mywork/mark.txt')

loren = Rugby(loren.pop(0),loren.pop(0),loren.pop(0),loren)
mark = OtherAthlete(mark.pop(0),mark.pop(0),mark.pop(0),mark)

def print_rugby(athlete):
    print(athlete.name)
    print(athlete.dob)
    print(athlete.squat)
    print(athlete.top3())

print_rugby(loren)
print_rugby(mark)
# 运行结果
# loren
# 2011-11-3
# 270
# ['4.11', '4.21', '4.21']
# mark
# 2010-2-4
# 300
# ['3.11', '3.11', '3.23']

四. 多继承

定义:class 子类名(父类名1, 父类名2, ...):
使用方式:对象名 = 子类名()
例:

class Father(): 
    def talk(self):
        print("---爸爸的表达能力---")

class Mather():
    def smart(self):
        print("---妈妈聪明的头脑---")

class Child(Father, Mather):
    pass

child = Child()
child.talk()
child.smart()

# 运行结果
# ---爸爸的表达能力---
# ---妈妈聪明的头脑---

多个父类有相同的属性或方法名,应该避免。

# 只会输出第一个父类的__init__方法和talk方法
class Father(): 
    def __init__(self):
        self.color = 'black'

    def talk(self):
        print("---爸爸的表达能力---")

class Mather():
    def __init__(self):
        self.color = 'white'
    def talk(self):
        print("--妈妈也能表达")
    def smart(self):
        print("---妈妈聪明的头脑---")

class Child(Father, Mather):
    pass

child2 = Child()
child2.talk()
child2.smart()
print(child2.color)

# 运行结果
# ---爸爸的表达能力---
# ---妈妈聪明的头脑---
# black

将上面的代码进行改进。

class Father(): 
    def __init__(self):
        self.color = 'black'
    def talk(self):
        print("---爸爸的表达能力---")

class Mather():
    def __init__(self):
        self.height = 170
    def smart(self):
        print("---妈妈聪明的头脑---")

class Child(Father,Mather):
    def __init__(self):
        Father.__init__(self)
        Mather.__init__(self)

child1 = Child()
child1.talk()
child1.smart()
print(child1.color)
print(child1.height)

# 运行结果
# ---爸爸的表达能力---
# ---妈妈聪明的头脑---
# black
# 170

使用Athlete的方法

在每个需要Athlete的时候,都需要把Athlete类的定义复制粘贴到要用的代码上方。

# 导入sys模块
import sys
# 将模块athlete.py添加到模块搜索路径(路径/athlete.py)
sys.path.append('路径')

# import athlete
# print(dir(athlete))
# 导入athlete模块,使用athlete模块下的所有代码
from athlete import *

loren = get_coach_data('mywork/loren.txt')
mark = get_coach_data('mywork/mark.txt')

loren = Rugby(loren.pop(0),loren.pop(0),loren.pop(0),loren)
mark = OtherAthlete(mark.pop(0),mark.pop(0),mark.pop(0),mark)

def print_rugby(athlete):

    print(athlete.name)
    print(athlete.dob)
    print(athlete.squat)
    print(athlete.top3())

print_rugby(loren)
print_rugby(mark)

# 运行结果
# loren
# 2011-11-3
# 270
# ['4.11', '4.21', '4.21']
# mark
# 2010-2-4
# 300
# ['3.11', '3.11', '3.23']

你可能感兴趣的:(python学习笔记,python,多态,面向对象编程,类)