7.类-面向对象的编程
7.1.类的定义
7.1.1.类的概述
面向对象更符合人类对客观世界的抽象和理解
一切皆对象
一只小狗,一把椅子,一张信用卡,一条巧克力。。。
一切对象,都有自己内在的属性
狗狗的品种、椅子的质地、信用卡的额度、巧克力的口味。。。
一切行为,皆是对象的行为
狗狗蹲下、椅子移动位置、刷信用卡、巧克力融化了。。。
类是对象的载体
不同年龄、肤色、品质的猫,每一只都是一个对象
他们有一个共同的特征:都是猫
我们可以把一类对象的公共特征抽象出来,创建通用的类
# 创建类class Cat():
"""模拟猫"""
def __init__(self, name):
"""初始化属性"""
self.name = name
def jump(self):
"""模拟猫跳跃"""
print(self.name + " is jumping")
# 用类创建实例
my_cat = Cat("Loser")
your_cat = Cat("Lucky")
# 调用属性
print(my_cat.name)
print(your_cat.name)
Loser
Lucky
# 调用方法
my_cat.jump()
your_cat.jump()
Loser is jumping
Lucky is jumping
7.1.2.类的定义
三要素:类名、属性、方法
类的命名
要有实际意义
驼峰命名法——组成的单词首字母大写
Dog、 CreditCard、 ElectricCar
# class 类名:
"""类前空两行"""
class Car():
"""对该类的简单介绍"""
pass
"""类后空两行"""
类的属性
# def __init__(self,要传递的参数) 初始化类的属性
class Car():
"""模拟汽车"""
def __init__(self, brand, model, year):
"""初始化汽车属性""" # 相当于类内部的变量
self.brand = brand # 汽车的品牌
self.model = model # 汽车的型号
self.year = year # 汽车出厂年份
self.mileage = 0 # 新车总里程初始化为0
类的方法
# 相对于类内部定义的函数
class Car():
"""模拟汽车"""
def __init__(self, brand, model, year):
"""初始化汽车属性""" # 相当于类内部的变量
self.brand = brand # 汽车的品牌
self.model = model # 汽车的型号
self.year = year # 汽车出厂年份
self.mileage = 0 # 新车总里程初始化为0
def get_main_information(self): # self不能省
"""获取汽车主要信息"""
print("品牌:{} 型号:{} 出厂年份:{}".format(self.brand, self.model, self.year))
def get_mileage(self):
"""获取总里程"""
return "行车总里程:{}公里".format(self.mileage)
7.2.创建实例
7.2.1.实例的创建与访问
实例的创建
将实例赋值给对象,实例化过程中,传入相应的参数
v = 类名(必要的初始化参数)
my_new_car = Car("Audi", "A6", 2018)
访问属性
print(my_new_car.brand)
print(my_new_car.model)
print(my_new_car.year)
Audi
A6
2018
调用方法
class Car():
"""模拟汽车"""
def __init__(self, brand, model, year):
"""初始化汽车属性""" # 相当于类内部的变量
self.brand = brand # 汽车的品牌
self.model = model # 汽车的型号
self.year = year # 汽车出厂年份
self.mileage = 0 # 新车总里程初始化为0
def get_main_information(self): # self不能省
"""获取汽车主要信息"""
print("品牌:{} 型号:{} 出厂年份:{}".format(self.brand, self.model, self.year))
def get_mileage(self):
"""获取总里程数"""
return "行车总里程:{}公里".format(self.mileage)
实例名.方法名(必要的参数)
my_new_car = Car("Audi", "A6", 2018)
my_new_car.get_main_information()
品牌:Audi 型号:A6 出厂年份:2018
mileage = my_new_car.get_mileage()
print(mileage)
行车总里程:0公里
7.2.2.修改属性
1、直接修改
先访问,后修改
my_old_car = Car("BYD", "宋", 2016)
print(my_old_car.mileage)
my_old_car.mileage = 12000
print(my_old_car.mileage)
0
12000
print(my_old_car.get_mileage())
行车总里程:12000公里
2、通过方法修改属性
class Car():
"""模拟汽车"""
def __init__(self, brand, model, year):
"""初始化汽车属性""" # 相当于类内部的变量
self.brand = brand # 汽车的品牌
self.model = model # 汽车的型号
self.year = year # 汽车出厂年份
self.mileage = 0 # 新车总里程初始化为0
def get_main_information(self): # self不能省
"""获取汽车主要信息"""
print("品牌:{} 型号:{} 出厂年份:{}".format(self.brand, self.model, self.year))
def get_mileage(self):
"""获取总里程数"""
return "行车总里程:{}公里".format(self.mileage)
def set_mileage(self, distance):
"""设置总里程数"""
self.mileage = distance
my_old_car = Car("BYD", "宋", 2016)
print(my_old_car.get_mileage())
my_old_car.set_mileage(8000)
print(my_old_car.get_mileage())
行车总里程:0公里
行车总里程:8000公里
3、继续拓展
禁止设置负里程
class Car():
"""模拟汽车"""
def __init__(self, brand, model, year):
"""初始化汽车属性""" # 相当于类内部的变量
self.brand = brand # 汽车的品牌
self.model = model # 汽车的型号
self.year = year # 汽车出厂年份
self.mileage = 0 # 新车总里程初始化为0
def get_main_information(self): # self不能省
"""获取汽车主要信息"""
print("品牌:{} 型号:{} 出厂年份:{}".format(self.brand, self.model, self.year))
def get_mileage(self):
"""获取总里程数"""
print("行车总里程:{}公里".format(self.mileage))
def set_mileage(self, distance):
"""设置总里程数"""
if distance >= 0:
self.mileage = distance
else:
print("里程数不能为负!")
def increment_mileage(self, distance):
"""总里程数累计"""
if distance >= 0:
self.mileage += distance
else:
print("新增里程数不能为负!")
my_old_car = Car("BYD", "宋", 2016)
my_old_car.get_mileage()
my_old_car.set_mileage(-8000)
my_old_car.get_mileage()
行车总里程:0公里
里程数不能为负!
行车总里程:0公里
# 将每次的里程数累加
my_old_car.get_mileage()
my_old_car.set_mileage(8000)
my_old_car.get_mileage()
my_old_car.increment_mileage(500)
my_old_car.get_mileage()
行车总里程:0公里
行车总里程:8000公里
行车总里程:8500公里
总结
类包含的信息量可以是极大的,可以创建无穷多的实例
高度的拟人(物)化,符合人类对客观世界的抽象和理解
7.3.类的继承
7.3.1.继承概述
看一下人在生物界的分支链
生物—动物界—脊索动物门—哺乳动物纲—灵长目—人科—人属—智人种
公共特征逐渐增加的过程
【问题】
假设二元系统: 人属 = {A人种, B人种, C人种。。。。}
为每一个人种构造一个类
方案一: 各自独立,分别构造各自人种的类
方案二:
1、将各人种公共特征提取出来,建立人属的类;
2、各人种继承上一级(人属)的公共特征,然后添加自身特殊特征,构建各自人种的类。
通常,我们选择方案二,因为他避免了过多的重复劳动
7.3.2.简单的继承
父类
class Car():
"""模拟汽车"""
def __init__(self, brand, model, year):
"""初始化汽车属性""" # 相当于类内部的变量
self.brand = brand # 汽车的品牌
self.model = model # 汽车的型号
self.year = year # 汽车出厂年份
self.mileage = 0 # 新车总里程初始化为0
def get_main_information(self): # self不能省
"""获取汽车主要信息"""
print("品牌:{} 型号:{} 出厂年份:{}".format(self.brand, self.model, self.year))
def get_mileage(self):
"""获取总里程数"""
print("行车总里程:{}公里".format(self.mileage))
def set_mileage(self, distance):
"""设置总里程数"""
if distance >= 0:
self.mileage = distance
else:
print("里程数不能为负!")
def increment_mileage(self, distance):
"""总里程数累计"""
if distance >= 0:
self.mileage += distance
else:
print("新增里程数不能为负!")
子类
格式:class 子类名(父类名):
新建一个电动汽车的类
class ElectricCar(Car):
"""模拟电动汽车"""
def __init__(self, brand, model, year):
"""初始化电动汽车属性"""
super().__init__(brand, model, year) # 声明继承父类的属性
自动继承父类的所有方法
my_electric_car = ElectricCar("NextWeek", "FF91", 2046)
my_electric_car.get_main_information()
品牌:NextWeek 型号:FF91 出厂年份:2046
7.3.3.给子类添加属性和方法
class ElectricCar(Car):
"""模拟电动汽车"""
def __init__(self, brand, model, year, bettery_size):
"""初始化电动汽车属性"""
super().__init__(brand, model, year) # 声明继承父类的属性
self.bettery_size = bettery_size # 电池容量
self.electric_quantity = bettery_size # 电池剩余电量
self.electric2distance_ratio = 5 # 电量距离换算系数 5公里/kW.h
self.remainder_range = self.electric_quantity*self.electric2distance_ratio # 剩余可行驶里程
def get_electric_quantit(self):
"""查看当前电池电量"""
print("当前电池剩余电量:{} kW.h".format(self.electric_quantity))
def set_electric_quantity(self, electric_quantity):
"""设置电池剩余电量,重新计算电量可支撑行驶里程"""
if electric_quantity >= 0 and electric_quantity <= self.bettery_size:
self.electric_quantity = electric_quantity
self.remainder_range = self.electric_quantity*self.electric2distance_ratio
else:
print("电量未设置在合理范围!")
def get_remainder_range(self):
"""查看剩余可行驶里程"""
print("当前电量还可以继续驾驶 {} 公里".format(self.remainder_range))
my_electric_car = ElectricCar("NextWeek", "FF91", 2046, 70)
my_electric_car.get_electric_quantit() # 获取当前电池电量
my_electric_car.get_remainder_range() # 获取当前剩余可行驶里程
当前电池剩余电量:70 kW.h
当前电量还可以继续驾驶 350 公里
my_electric_car.set_electric_quantity(50) # 重设电池电量
my_electric_car.get_electric_quantit() # 获取当前电池电量
my_electric_car.get_remainder_range() # 获取当前剩余可行驶里程
当前电池剩余电量:50 kW.h
当前电量还可以继续驾驶 250 公里
7.3.4.重写父类的方法——多态
class ElectricCar(Car):
"""模拟电动汽车"""
def __init__(self, brand, model, year, bettery_size):
"""初始化电动汽车属性"""
super().__init__(brand, model, year) # 声明继承父类的属性
self.bettery_size = bettery_size # 电池容量
self.electric_quantity = bettery_size # 电池剩余电量
self.electric2distance_ratio = 5 # 电量距离换算系数 5公里/kW.h
self.remainder_range = self.electric_quantity*self.electric2distance_ratio # 剩余可行驶里程
def get_main_information(self): # 重写父类方法
"""获取汽车主要信息"""
print("品牌:{} 型号:{} 出厂年份:{} 续航里程:{} 公里"
.format(self.brand, self.model, self.year, self.bettery_size*self.electric2distance_ratio))
def get_electric_quantit(self):
"""查看当前电池电量,重新计算电量可支撑行驶里程"""
print("当前电池剩余电量:{} kW.h".format(self.electric_quantity))
def set_electric_quantity(self, electric_quantity):
"""设置电池剩余电量"""
if electric_quantity >= 0 and electric_quantity <= self.bettery_size:
self.electric_quantity = electric_quantity
self.remainder_range = self.electric_quantity*self.electric2distance_ratio
else:
print("电量未设置在合理范围!")
def get_remainder_range(self):
"""查看剩余可行驶里程"""
print("当前电量还可以继续驾驶 {} 公里".format(self.remainder_range))
my_electric_car = ElectricCar("NextWeek", "FF91", 2046, 70)
my_electric_car.get_main_information()
品牌:NextWeek 型号:FF91 出厂年份:2046 续航里程:350 公里
7.3.5.类中的引用对象
把电池抽象成一个对象
逻辑更加清晰
class Bettery():
"""模拟电动汽车的电池"""
def __init__(self, bettery_size = 70):
self.bettery_size = bettery_size # 电池容量
self.electric_quantity = bettery_size # 电池剩余电量
self.electric2distance_ratio = 5 # 电量距离换算系数 5公里/kW.h
self.remainder_range = self.electric_quantity*self.electric2distance_ratio # 剩余可行驶里程
def get_electric_quantit(self):
"""查看当前电池电量"""
print("当前电池剩余电量:{} kW.h".format(self.electric_quantity))
def set_electric_quantity(self, electric_quantity):
"""设置电池剩余电量,计重新算电量可支撑行驶里程"""
if electric_quantity >= 0 and electric_quantity <= self.bettery_size:
self.electric_quantity = electric_quantity
self.remainder_range = self.electric_quantity*self.electric2distance_ratio
else:
print("电量未设置在合理范围!")
def get_remainder_range(self):
"""查看剩余可行驶里程"""
print("当前电量还可以继续驾驶 {} 公里".format(self.remainder_range))
class ElectricCar(Car):
"""模拟电动汽车"""
def __init__(self, brand, model, year, bettery_size):
"""初始化电动汽车属性"""
super().__init__(brand, model, year) # 声明继承父类的属性
self.bettery = Bettery(bettery_size) # 电池
def get_main_information(self): # 重写父类方法
"""获取汽车主要信息"""
print("品牌:{} 型号:{} 出厂年份:{} 续航里程:{} 公里"
.format(self.brand, self.model, self.year,
self.bettery.bettery_size*self.bettery.electric2distance_ratio))
my_electric_car = ElectricCar("NextWeek", "FF91", 2046, 70)
my_electric_car.get_main_information() # 获取车辆主要信息
品牌:NextWeek 型号:FF91 出厂年份:2046 续航里程:350 公里
my_electric_car.bettery.get_electric_quantit() # 获取当前电池电量
当前电池剩余电量:70 kW.h
my_electric_car.bettery.set_electric_quantity(50) # 重设电池电量
my_electric_car.bettery.get_electric_quantit() # 获取当前电池电量
当前电池剩余电量:50 kW.h
my_electric_car.bettery.get_remainder_range() # 获取当前剩余可行驶里程
当前电量还可以继续驾驶 250 公里
7.4.作业练习
类的定义与调用:
1、构造一个银联信用卡的类,
*包含如下属性:
顾客姓名
信用卡授信额度
当前额度
单次刷卡金额上限
*包含如下方法:
分别获得上述属性的方法;
对授信额度进行修改的方法;
对单次刷卡金额上限修改的方法;
实现刷卡方法,传入一个刷卡金额,先判断是否超过单次刷卡金额上限以及当前额度是否够用,如合理,则执行刷卡,将当前额度减去刷卡金额。
*创建信用卡实例并执行调用相应的属性和方法
类的继承:
2、通过继承银联信用卡的类,构造中国银行信用卡的类:
实现对银联信用卡类的继承;
新增加属性:中国银行信用卡积分、优惠店铺列表;
重写刷卡方法:
传入消费店铺名称和消费金额,如果店铺名称在优惠店铺列表中,则刷卡金额打95折;
每消费10元,信用卡积分增加1分;
保留父类刷卡方法的其他功能。
新增如下方法:
获得用户积分的方法;
设置优惠店铺列表的方法。
答案:
1.
class UnionPayCreditCard():
'''构造一个银联信用卡的类'''
def __init__(self, name, amount, current_amount, single_limit):
''' 顾客姓名 信用卡授信额度 当前额度 单次刷卡金额上限 '''
self.name = name
self.amount = amount
self.current_amount = current_amount
self.single_limit = single_limit
'''对于每个属性分别设置getter'''
def get_name(self):
return self.name
def get_amount(self):
return self.amount
def get_current_amount(self):
return self.current_amount
def get_single_limit(self):
return self.single_limit
def modify_amount(self, new_amount):
'''对授信额度进行修改的方法'''
self.amount = new_amount
print("你的消费额度修改为{}元".format(self.amount))
def modify_single_amount(self, new_single_amount):
'''对单次刷卡金额上限修改的方法'''
self.single_limit = new_single_amount
print("你的消费上限修改为{}元".format(self.single_limit))
def consume(self, cost):
'''实现刷卡方法,传入一个刷卡金额, 先判断是否超过单次刷卡金额上限以及 当前额度是否够用,如合理,则执行刷 卡,将当前额度减去刷卡金额'''
if cost < self.single_limit and cost < self.amount:
self.amount -= cost
print("你本次消费{}元,剩余额度为{}元".format(cost, self.amount))
else:
print("你的消费金额无法支付,请检查你的信用额度!")
return self.amount
def start():
card = UnionPayCreditCard("Tony", 10000, 5000, 1000)
name = card.get_name()
amount = card.get_amount()
current_amount = card.get_current_amount()
single_limit = card.get_single_limit()
print("name={}, amount={}, current_amount={}, single_limit={}".format( name, amount, current_amount, single_limit))
card.modify_amount(20000)
card.modify_single_amount(5000)
card.consume(2000)
card.consume(100000)
if __name__ == "__main__":
start()
name=Tony, amount=10000, current_amount=5000, single_limit=1000
你的消费额度修改为20000元
你的消费上限修改为5000元
你本次消费2000元,剩余额度为18000元
你的消费金额无法支付,请检查你的信用额度!
2.
class BankOfChinaCreditCard(UnionPayCreditCard):
def __init__(self, name, amount, current_amount, single_limit):
super().__init__(name, amount, current_amount, single_limit)
self.integral = 0
self.discount_shop = ["Huawei旗舰店", "小米旗舰店", "Apple旗舰店"]
def consume(self, shop_name, cost):
'''重写刷卡方法'''
if cost < self.single_limit and cost < self.amount and shop_name in self.discount_shop:
cost *= 0.95
self.integral = cost // 10
print("你本次消费{}元, 优惠{}元,获得积分{}, 已有积分{}".format(cost, 0.05 * cost, cost // 10, self.integral))
def get_integral(self):
'''获得用户积分的方法'''
print("你的积分为{}".format(self.integral))
return self.integral
def set_discount_shop(self, shop_name):
'''设置优惠店铺列表的方法'''
self.discount_shop.append(shop_name)
return self.discount_shop
def start():
card = BankOfChinaCreditCard("Tony", 10000, 5000, 1000)
name = card.get_name()
amount = card.get_amount()
current_amount = card.get_current_amount()
single_limit = card.get_single_limit()
integral = card.get_integral()
print("name={}, amount={}, current_amount={}, single_limit={}, integral={}".format( name, amount, current_amount, single_limit, integral))
card.modify_amount(20000)
card.modify_single_amount(5000)
card.consume( "小米旗舰店", 2000)
card.consume("Apple旗舰店", 100000)
if __name__ == "__main__":
start()
你的积分为0
name=Tony, amount=10000, current_amount=5000, single_limit=1000, integral=0
你的消费额度修改为20000元
你的消费上限修改为5000元
你本次消费1900.0元, 优惠95.0元,获得积分190.0, 已有积分190.0