Pthon第九课:对象、类、实例(class)

一、类

物以类聚,人以群分

  • 类就是多个类似事物组成的群体的统称,能帮助我们快速理解和判断事物的归属。
  • 类之所以称为类,就是因为类下面有无数个相似却不同的个例。
  • 在Python中,将类的个例,称作为“实际的例子”,简称实例。
  • 类就是统称,一类物品的统称。实例就是一个具体存在特指的一个事物。相似的实例就可以归到同一类中。

二、对象

  • 对象包含类与实例,比如str是类对象,'hello’是实例对象。
  • 在Python中,一切皆对象。

三、创建类与调用类

1、类的创建

羽泉、你、我都是音乐人------这句话,在Python中翻译过来就是: 羽泉、你、我都属于“音乐人”这个类,羽泉、你、我都是“音乐人”这个类中的实例;我们都存在一些相同点:喜欢音乐、艺名、会唱歌、能跳舞。

  1. 属性(attribute):用来描述事物性质的,比如喜欢云月、艺名
  2. 方法(method):用来描述事物能做什么,比如能唱歌、能跳舞
  3. 举例:字符串,属性有引号、下标,方法有都可以进行拼接操作
  • 每个类都有自己的独特的属性和方法,是这个类的所有实例都共享的。换言之,每个实例都可以调用类中所有的属性和方法。
  • Python中,各个类的属性与方法需要我们自行创建
    在这里插入图片描述
class Musician:
    loveMusic = True

    def sing(self):
        print('我爱唱歌')

在这里插入图片描述

# 创建一个”明星”类,并为其创建一个属性(墨镜)和一个方法(与粉丝合影)。

class Star:
    attribute = '墨镜'

    def mothed(self):
        print('与粉丝合影')

2、类的调用

(1)单个实例
class Musician:
    lovemusic = True

    def sing(self):
        print('想唱就唱,要唱得响亮')


laoFan = Musician()
print('音乐人老樊')
laoFan.sing()
# 输出结果:
音乐人老樊
想唱就唱,要唱得响亮
  • 关键在于后三行代码,laoFan = Musician() 这就是通过音乐人这个类创建laoFan这个实例。这个过程叫做类的实例化。
    在这里插入图片描述
class Musician:
    lovemusic = True

    def sing(self):
        print('想唱就唱,要唱得响亮')

laofan = Musician()
print(laofan)
print(type(laofan))

# 输出结果
<__main__.Musician object at 0x10bbfb2b0>
<class '__main__.Musician'>
  • 打印的第一行,<main.Musician object at 0x10bbfb2b0>就是通过Musician这个类创建的laofan这个实例,这是这个实例在电脑上中的内存地址;
  • 第二行说明了laofan这个实例属于Musician这个类。
  • 当laoFan这个实例创造出来之后,它可以调用Musician这个类中的属性与方法。

1、调用类属性: 实例名.属性名
2、调用类方法: 实例名.方法名()

(2)多个实例
  • 既然说类是相似实例的统称,那么,也能创建多个实例
class Musician:
    lovemusic = True

    def sing(self):
        print('想唱就唱,要唱得响亮')


laofan = Musician()
print('因育儿老樊')
laofan.sing()

diamond = Musician()
print('音乐人刘人语')
diamond.sing()

# 输出结果
音乐人老樊
想唱就唱,要唱得响亮
音乐人刘人语
想唱就唱,要唱得响亮
  • 这里,就通过Musician这个类,创建了laoFan与diamond两个实例,当然你还可以创建更多实例,看你的需求。
  • 类就像工厂一样,可以通过一条生产线制造多个商品。因此,类也被称为“实例工厂”。

四、创建类的两大要素

1、self参数

  • slef的作用:在类的实例化中接收传入的数据, 在代码中运行。
class Musican:
    name = '羽泉'

    def sing(self):
        print(self.name + '音乐人')


singer = Musican()
print(singer.name)
singer.sing()

# 输出结果
羽泉
羽泉音乐人
  • 这就是self的独特之处,它的作用就是先在类方法中占一个位置,当实例创建调用类方法的时候,它就会将self.name也就是类中的name放入方法中,也就会把’羽泉’放入方法中。
  • 这就是类方法中调用类属性需要使用self。
  • 同理,如果类中的一个类方法需要调用另一个类方法,依然需要使用slef。
class Musican:
    name = 'Justin Biber'

    def hello(self):
        print('Hello, everybody')

    def sing(self):
        self.hello()
        print(self.name+'is a musican')

singer = Musican()
singer.sing()

# 输出结果
Hello, everybody
Justin Biberis a musican
  • 创建实例后,实例调用方法singer.sing(),在singer.sing()方法执行的时候,会自动调用self.hello()方法,因此’Hello, everybody"这段文字也会出现。
  • 类方法中调用类内部属性或者是其他方法时,需要使用self来代表实例。

2、初始化方法

  • 每个类中都存在一个初始化方法,这个方法不需要调用,在通过类创建实例对象的时候初始化方法会自动执行。
  • 定义初始化方法:def init(self): ,init两边是双下划线。
class Musican:
    def __init__(self):
        print('大家好,这是初始化方法')

lironghao = Musican()

# 输出结果:
大家好,这是初始化方法
  • 我们创建了liRongHao = Musician() 这个实例,没有调用,init初始化方法就自动执行了。
  • 利用init初始化方法的特点,我们可以在初始化方法中完成类属性的创建及类属性的赋初值。
class Musican:
    def __init__(self):
        self.glass = '墨镜'
        self.microphone = 'manny'

    def intr(self):
        print('我出门,必须戴%s'%self.glass)
        print('我有%s个麦克风'%self.microphone)

silence = Musican()
silence.intr()

# 输出结果:
我出门,必须戴墨镜
我有manny个麦克风
  • 初始化方法中,除了可以设置固定值之外,还可以接收其他参数,使得传入的数据灵活多变。
class Musican:
    def __init__(self,name,anothername,music):
        self.name = name
        self.anothername = anothername
        self.music =music

    def intr(self):
        print('各位歌迷好,我是%s'%self.name)
        print('熟悉我的人,都叫我%s'%self.anothername)

    def sing(self):
        print('我为大家唱一首%s'%self.music)

jam = Musican('萧敬腾','雨神','王妃')
jam.intr()
jam.sing()

# 输出结果:
各位歌迷好,我是萧敬腾
熟悉我的人,都叫我雨神
我为大家唱一首王妃

3、str(self)方法

  • str(self)方法与__init__(self)方法类似,在类中有着特殊功能。
  • 在类实例化对象时,将此方法绑定到对象中;当我们打印实例化对象时,就会自动打印出__str__(self)方法中的内容。
class Grandpa:

    def __str__(self):
        return '我是你师傅,我是你大爷'


yeye = Grandpa()
print(yeye)

# 输出结果:
我是你师傅,我是你大爷

五、面向对象编程

  • 在之前的面向过程编程,我们需要分析出解决问题的步骤,及首先干什么,然后干什么,最后干什么;
  • 而面向对象编程,会将程序看成是对象的集合(一切皆对象)。面向对象编程,不考虑实现功能的步骤;而是考虑实现这个功能需要设计什么样的类,这个类中有哪些属性和方法。然后,通过这个类创建一个实例对象,让对象来调用类属性与类方法。
import math


# 设置输入函数
def boss_choice():
    # 输入内容
    type = int(input('请输入需要的押运方式(1,押运人数恒定;2,押运次数恒定):'))
    quantity = float(input('请输入需要押运的运量(1代表标准,可输入小数或倍数):'))

    # 当押运人数恒定时,输入即将投入的镖师人数
    if type == 1:
        others = int(input('请输入投入的镖师人数,请输入整数:'))
    # 当押运次数恒定时,输入预计的押运次数
    elif type == 2:
        others = int(input('请输入押运次数,请输入整数:'))
    # 函数返回一个元组
    return type, quantity, others


# 设置计算函数
def calculate(data_input):
    # 调用参数,参数为元组
    type = data_input[0]
    quantity = data_input[1]
    others = data_input[2]

    # 打印计算结果
    print('计算结果如下:')
    if type == 1:
        num = math.ceil(round((100 * quantity) / (20 * others), 2))
        print('{:.1f}个标准运量,在投入{}个镖师的情况下,需要押运{}次才能将此趟镖押运完毕.'.format(quantity, others, num))
    elif type == 2:
        num = math.ceil(round((100 * quantity) / (20 * others), 2))
        print('%.1f个标准运量,在%d次押运的情况下,需要%d个镖师才能将此趟镖押运完毕.' % (quantity, others, num))


# 设置主函数,分别调用boss_choice()函数和calculate()函数
def calculate_main():
    # 调用boo_choice()给变量赋值
    data_input = boss_choice()
    # 将变量作为calculate()函数的参数
    calculate(data_input)


# 调用主函数
calculate_main()
  • 观察之前我们的龙门镖局计算的代码,然后我们现在用面向对象编程的思路来改造一下代码。
import math


class Program:
    def __init__(self):
        self.key = 1

    # 工时计算
    def Boss_choice(self):
        # 设置默认参数
        self.type = int(input('请选择需要的押运方式(1,押运人数恒定;2,押运次数恒定):'))
        self.quantity = float(input('请输入需要押运的运量(1代表标准,可输入小数或倍数):'))
        if self.type == 1:
            self.others = int(input('请输入投入的镖师人数,请输入整数:'))
        elif self.type == 2:
            self.others = int(input('请输入押运次数,请输入整数:'))

    # 计算工作量
    def calculate(self):
        print('计算结果如下:')
        if self.type == 1:
            self.num = math.ceil(round((100 * self.quantity) / (20 * self.others), 2))
            print('{:.1f}个标准运量,在投入{}个镖师的情况下,需要押运{}次才能将此趟镖押运完毕.'.format(self.quantity, self.others, self.num))

        elif self.type == 2:
            self.num = math.ceil(round((100 * self.quantity) / (20 * self.others), 2))
            print('%.1f个标准运量,在%d次押运的情况下,需要%d个镖师才能将此趟镖押运完毕.' % (self.quantity, self.others, self.num))

    def again(self):
        num = input('是否继续计算?继续请输入有y,其他按键结束程序')
        print()
        # 当输入y时,将初始值y赋值为0
        if num != 'y':
            self.key = 0

    def res(self):
        while self.key == 1:
            self.Boss_choice()
            self.calculate()
            self.again()
        print('工作辛苦了!')


pro = Program()
pro.res()

在这里插入图片描述

六、类的继承

在这里插入图片描述

  • 既然“X类继承了Y类”,我们就可以称:X类是Y类的子类,Y类是X类的父类(或者超类)。
  • 类的继承,让子类拥有了父类的所有属性和方法。这样就可以实现代码复用。

1、类的一对一继承

在这里插入图片描述

class Musican:
    glasses = '墨镜'
    lovemousic = True

    def sing(self):
        print('想唱就唱,要唱得响亮')

class Rapper(Musican):
    pass

mcHotdog = Rapper()
print(mcHotdog.glasses)
mcHotdog.sing()

# 输出结果:
墨镜
想唱就唱,要唱得响亮
  • 好多类,在创建的时候没有括号啊,就像class Car: ,难道Car这个类没有父类吗?其实Car也是有父类的。当创建的类没有小括号时,这个类的父类就是Object。
# 直接运行
class Car:
    wheel = 4

    def run(self):
        print('有%d个轮子,可以飞速的行驶' % self.wheel)


class BMW(Car):
    pass


BENZ600 = Car()  # 使用Car类创建奔驰600
BMW320 = BMW()  # 使用BMW类创建BMW320
print("验证:子类创建的实例也属于父类")
print(isinstance(BENZ600, Car))
print(isinstance(BMW320, Car))
print()
print("验证:父类创建的实例不属于子类")
print(isinstance(BENZ600, BMW))
print()
print("验证:所有类创建的实例都属于根类")
print(isinstance(BENZ600, object))
print(isinstance(BMW320, object))
  • 在类的继承中,子类属于父类;子类创建的实例也属于父类。
    在这里插入图片描述
  • 除了一对一的继承外,类的继承中还存在多层继承和多重继承。

2、多层继承

  • 子类不仅仅可以继承父类, 还可以继承父类的父类、父类的父类的父类……

在这里插入图片描述

# 明星类
class Star:
    glasses = "墨镜"


# 音乐人继承了明星
class Musician(Star):
    loveMusic = True


# Rapper继承了音乐人
class Rapper(Musician):
    pass


csunYuk = Rapper()
print(csunYuk.glasses)
print(csunYuk.loveMusic)

# 输出结果:
墨镜
True

3、多重继承

  • 一个类可以继承多个类, 语法是class Z(X,Y) 。子类会与左边的父类更相似。
# 音乐人
class Musician:
    lovemusic = True

    def intr(self):
        print('我喜欢音乐,我来自音乐界')


# 演说家
class Orator:
    speak = '流利地说'

    def intr(self):
        print('我喜欢演说,我来自演讲界')


# Rapper继承了音乐人和演说家
class Rapper(Musician,Orator):
    pass


caixukun = Rapper()
print(caixukun.lovemusic)
print(caixukun.speak)
caixukun.intr()

# 输出结果:
True
流利地说
我喜欢音乐,我来自音乐界
  • csunYuk继承了父类Musician的属性loveMusic,也继承了父类Orator的属性speak;当两个父类都具有intr()类方法时,它会优先继承左边的父类,也就是父类Musician的方法。
  • 多重继承中, 子类继承于多个父类的属性与方法, 但是优先继承于左边父类的属性与方法。
    在这里插入图片描述

4、类的定制

  • 子类可以在继承父类的基础上进行定制: 可以创建新属性、新方法;也可以改变继承到的属性或方法。
  • 类的定制则包括两种操作:新增代码和重写代码。
(1)新增代码
# 音乐人
class Musician:
    lovemusic = True

    def intr(self):
        print('我喜欢音乐,我来自音乐界')

    def sing(self):
        print('想唱就唱,要唱得响亮')


# 演说家
class Rapper(Musician):
    garrulous = True

    def composition(self):
        print('我可以创作简单的歌词')


caixukun=Rapper()
print(caixukun.lovemusic)
print(caixukun.garrulous)
caixukun.composition()

# 输出结果:
True
True
我可以创作简单的歌词
(2)重写代码
  • 重写代码最好是在继承方法的基础上通过代码的调整完成定制,如:
class Musican:

    def sing(self):
        print('我是一个歌手')


# Rapper继承Musican
class Rapper(Musican):  # 类的继承
    def sing(self):  # 类的定制,更改方法
        print('我是一个rapper,我以说唱的形式进行歌唱')


caixukun = Rapper()
caixukun.sing()

七、练习

  1. 你去参加非诚勿扰活动,要在活动上,介绍自己的姓名\年龄与籍贯。创建一个类叫Maleguests,这个类中具有两个属性: sex = “M”,marriage = “False”; 类中有一个方法,叫hello方法,可以打印“各位女嘉宾好”
class Maleguests():
    sex = 'M'
    mariage = False

    def hello(self):
        print('各位女嘉宾,大家好!')

liudehua = Maleguests()
print(liudehua.sex)
print(liudehua.mariage)
liudehua.hello()

# 输出结果:
M
False
各位女嘉宾,大家好!
  1. 有多个男嘉宾去参加非诚勿扰活动,要在活动上,介绍自己的姓名\年龄与籍贯。创建一个类叫Maleguests,这个类中具有一个方法叫sayHi,sayHi方法可以介绍自己的姓名\年龄与籍贯。例如“各位女嘉宾好我叫张三,我今年28岁,我来自广州”; 姓名\年龄与籍贯是可以根据需要改变的。
class Maleguests:
    def __init__(self, name, age, home):
        self.name = name
        self.age = age
        self.home = home

    def sayHi(self):
        print('大家好,我叫%s,我今年%s岁,来自%s,很高兴认识你们!' % (self.name, self.age, self.home))


liudehua = Maleguests('刘德华', '45', '香港')
liudehua.sayHi()
songweilong = Maleguests('宋威龙', '30', '八里台')
songweilong.sayHi()

# 输出结果:
大家好,我叫刘德华,我今年45岁,来自香港,很高兴认识你们!
大家好,我叫宋威龙,我今年30岁,来自八里台,很高兴认识你们!

  1. 每个人都有多重身份, 比如说一个学生, 他在学校里的身份就是学生,进行学习;回到家里,他的身份就是儿子,需要照顾父母;他不仅有着学生的属性与方法,还有着儿子的属性与方法。
class Student:
    stu_no = '2034'

    def study(self):
       print('好好学习,天天向上')


class Child:
    status = '父母的小孩'

    def care(self):
        print('赡养父母')


class Son(Student,Child):
    pass


lilei = Son()
print(lilei.stu_no)
print(lilei.status)
lilei.study()
lilei.care()

# 输出结果:
2034
父母的小孩
好好学习,天天向上
赡养父母
  1. 有一个徒弟厨师,跟着师父学做煎饼果子,师父教给徒弟做传统的煎饼果子,与台湾手抓饼;徒弟在学习后又出国深造了几年,不仅仅能做手抓饼,还可以做中西方口味融合的煎饼果子。
class Master:
    status = '厨师'

    def cake(self):
        print('制作手抓饼')

    def cook(self):
        print('制作传统的煎饼果子')


class apprentice(Master):
    def cook(self):
        print('制作中西合璧的煎饼果子')

print('师傅')
shifu = Master()
print(shifu.status)
shifu.cake()
shifu.cook()
print()
print('徒弟')
tudi = apprentice()
print(tudi.status)
tudi.cake()
tudi.cook()

# 输出结果:
师傅
厨师
制作手抓饼
制作传统的煎饼果子

徒弟
厨师
制作手抓饼
制作中西合璧的煎饼果子
  1. 帮共享单车公司完成一个共享单车的租借平台。 在这个共享平台中,大家可以查看到所有的单车,能够进行租借、还车功能,也可以把自己的单车共享出来,放在平台上,让其他人使用。要求具备以下功能:查询车辆、共享车辆、租借车辆、归还车辆。
class Bike:
    # 初始化方法,NO代表车辆编号,age代表使用年限
    # state代表车辆状态,0代表d待租借,1代表租借中
    def __init__(self, NO, age, state=0):
        self.NO = NO
        self.age = age
        self.state = state

    def __str__(self):
        if self.state == 0:
            status = '待租借'
        else:
            status = '租借中'

        return '车辆编号%d,已经运行%d年,车辆状态:%s' % (self.NO, self.age, status)


class Manage:
    # 定义一个列表,用于存储所有车辆信息
    bike_list = []

    def __init__(self):
        bikeA = Bike(1001, 1)
        bikeB = Bike(1002, 1)
        bikeC = Bike(1003, 1)
        self.bike_list.append(bikeA)
        self.bike_list.append(bikeB)
        self.bike_list.append(bikeC)

    # 系统菜单
    def menu(self):
        print('=========欢迎使用共享单车租借系统=========')
        while True:
            print('1. 查询所有车辆\n2. 共享车辆\n3. 租借车辆\n4. 归还车辆\n5. 退出系统\n')
            select = int(input('请输入所选功能对应的数字:'))

            if select == 1:
                # 单车信息
                self.info_bike()
            elif select == 2:
                # 共享单车
                self.add_bike()
            elif select == 3:
                # 租借单车
                self.lease_bike()
            elif select == 4:
                # 归还单车
                self.revert_bike()
            elif select == 5:
                # 退出系统
                print('成功退出系统,欢迎再次使用。祝您生活愉快!')
                break

    # 单车信息
    def info_bike(self):
        print('所有车辆信息如下:')
        for bike in self.bike_list:
            print(bike)

    # 共享单车
    def add_bike(self):
        new_NO = int(input('请输入车辆编码:'))
        new_age = float(input('请输入车辆使用年限:'))

        new_bike = Bike(new_NO, new_age)
        self.bike_list.append(new_bike)
        print('车辆共享成功!')

    # 租借车辆
    def lease_bike(self):
        lease_NO = int(input('请输入租借的车辆编号:'))
        res = self.selec_bike(lease_NO)

        if res != None:
            # 车辆租借中
            if res.state == 1:
                print('你来晚了,车辆被借走了~')
            else:
                print('租借成功,欢迎使用绿色出行!')
                res.state = 1

        else:
            print('该车辆不存在')

    def selec_bike(self, NO):
        for bike in self.bike_list:
            if bike.NO == NO:
                return bike

    def revert_bike(self):
        revert_NO = int(input('请输入归还车辆编号:'))
        res = self.selec_bike(revert_NO)

        if res != None:
            if res.state == 1:
                print('还车成功,期待下次使用!')
                res.state = 0
            else:
                print('车辆整备完成,等待租借!')
        else:
            print('该车辆不存在,想必是您输错了~')
user = Manage()
user.menu()
# 输出结果如下:
=========欢迎使用共享单车租借系统=========
1. 查询所有车辆
2. 共享车辆
3. 租借车辆
4. 归还车辆
5. 退出系统

请输入所选功能对应的数字:1
所有车辆信息如下:
车辆编号1001,已经运行1年,车辆状态:待租借
车辆编号1002,已经运行1年,车辆状态:待租借
车辆编号1003,已经运行1年,车辆状态:待租借
1. 查询所有车辆
2. 共享车辆
3. 租借车辆
4. 归还车辆
5. 退出系统

请输入所选功能对应的数字:2
请输入车辆编码:1009
请输入车辆使用年限:1
车辆共享成功!
1. 查询所有车辆
2. 共享车辆
3. 租借车辆
4. 归还车辆
5. 退出系统

请输入所选功能对应的数字:3
请输入租借的车辆编号:1009
租借成功,欢迎使用绿色出行!
1. 查询所有车辆
2. 共享车辆
3. 租借车辆
4. 归还车辆
5. 退出系统

请输入所选功能对应的数字:3
请输入租借的车辆编号:1008
该车辆不存在
1. 查询所有车辆
2. 共享车辆
3. 租借车辆
4. 归还车辆
5. 退出系统

请输入所选功能对应的数字:4
请输入归还车辆编号:1009
还车成功,期待下次使用!
1. 查询所有车辆
2. 共享车辆
3. 租借车辆
4. 归还车辆
5. 退出系统

请输入所选功能对应的数字:5
成功退出系统,欢迎再次使用。祝您生活愉快!
发布了15 篇原创文章 · 获赞 0 · 访问量 253

猜你喜欢

转载自blog.csdn.net/fightingoyo/article/details/104198501