类与面向对象编程简介
我们上一章介绍了函数,虽然函数在工作中的应用非常广泛,但仅靠函数还无法充分表达现实生活中复杂的实体和行为。因此,我们引入了面向对象编程(OOP)的概念,通过类来更好地抽象和表示现实世界中的事物。本文将详细介绍类的定义及其用法,帮助读者更好地理解和应用面向对象编程。
一、为什么选择面向对象编程?
面向对象编程(OOP)更加符合我们对客观世界的抽象和理解。在现实生活中,万事万物都可以被视为对象,每个对象都有其内在的属性和行为。例如:
- 小狗:品种、性别、年龄是它的属性;蹲下、奔跑、咬骨头是它的行为。
- 椅子:样式、质地是它的属性;坐下、站起来是它的行为。
- 信用卡:额度、归属银行是它的属性;消费、还款是它的行为。
通过面向对象编程,我们可以在计算机语言中构造具有属性和行为的对象,从而更直观地模拟现实世界。
二、类的定义
类是对象的载体,用于抽象一类对象的共同特征。类的定义包含三个要素:类名、属性和方法。
1. 类名
类名应具有实际意义,通常采用驼峰命名法(首字母大写,单词间无空格)。例如:
Cat
(猫)Car
(汽车)
2. 属性
类的属性可以视为类内部的变量,通过__init__
方法进行初始化。例如:
def __init__(self, brand, model, year):
self.brand = brand
self.model = model
self.year = year
self.mileage = 0
3. 方法
类的方法类似于类内部的函数,用于定义对象的行为。例如:
def get_info(self):
print(f"Brand: {self.brand}, Model: {self.model}, Year: {self.year}")
def get_mileage(self):
return self.mileage
三、创建类的实例
定义好类后,可以通过类名和必要的初始化参数创建实例。例如:
print(my_car.brand) # 输出: Audi
my_car.get_info() # 输出: Brand: Audi, Model: A6, Year: 2018
四、修改类的属性
类的属性可以通过直接赋值或定义方法进行修改。例如:
print(my_car.get_mileage()) # 输出: 12000
def set_mileage(self, new_mileage):
if new_mileage >= 0:
self.mileage = new_mileage
else:
print("Mileage cannot be negative")
my_car.set_mileage(8000)
print(my_car.get_mileage()) # 输出: 8000
五、类的继承
类之间可以存在继承关系,子类可以继承父类的属性和方法,并可以添加新的属性和方法或重写父类的方法。例如:
def __init__(self, brand, model, year, battery_capacity):
super().__init__(brand, model, year)
self.battery_capacity = battery_capacity
self.battery_level = battery_capacity
self.electric_to_distance_ratio = 5
self.remaining_distance = self.battery_level * self.electric_to_distance_ratio
def get_battery_level(self):
print(f"Battery Level: {self.battery_level}")
def set_battery_level(self, new_level):
if 0 <= new_level <= self.battery_capacity:
self.battery_level = new_level
self.remaining_distance = self.battery_level * self.electric_to_distance_ratio
else:
print("Battery level out of range")
def get_remaining_distance(self):
print(f"Remaining Distance: {self.remaining_distance}")
my_electric_car = ElectricCar("Tesla", "Model S", 2022, 70)
my_electric_car.get_battery_level() # 输出: Battery Level: 70
my_electric_car.set_battery_level(50)
my_electric_car.get_remaining_distance() # 输出: Remaining Distance: 250
六、总结
面向对象编程通过类和对象的定义,使编程更加贴近现实世界的抽象和理解。类的定义包含类名、属性和方法,通过类可以创建实例并对其进行操作。类的继承使得代码复用更加高效,减少了重复劳动。
习题
单选题
-
为什么需要面向对象编程?
- A. 因为面向对象编程可以减少代码量
- B. 因为面向对象编程更加符合我们对客观世界的抽象与理解
- C. 因为面向对象编程可以提高程序运行速度
- D. 因为面向对象编程可以减少内存占用
答案: B
-
类的定义包含哪三个要素?
- A. 类的名称、类的属性、类的方法
- B. 类的名称、类的变量、类的函数
- C. 类的属性、类的方法、类的实例
- D. 类的名称、类的实例、类的函数
答案: A
-
类的命名推荐使用哪种命名法?
- A. 下划线命名法
- B. 驼峰命名法
- C. 全部小写
- D. 全部大写
答案: B
-
在类的定义中,
__init__
方法的作用是什么?- A. 定义类的方法
- B. 初始化类的属性
- C. 创建类的实例
- D. 定义类的名称
答案: B
-
类的继承表示的是什么?
- A. 子类可以继承父类的属性和方法
- B. 父类可以继承子类的属性和方法
- C. 类之间的属性和方法相互继承
- D. 类之间的属性和方法不能继承
答案: A
-
子类如何调用父类的
__init__
方法?- A. 使用
super().__init__()
- B. 使用
parent().__init__()
- C. 使用
self.__init__()
- D. 使用
base().__init__()
答案: A
- A. 使用
-
子类可以对父类的方法进行什么操作?
- A. 删除
- B. 修改
- C. 重写
- D. 添加
答案: C
-
类的实例化指的是什么?
- A. 定义类的名称
- B. 定义类的属性
- C. 创建类的具体对象
- D. 定义类的方法
答案: C
-
如何访问类的属性?
- A. 实例名.属性名
- B. 类名.属性名
- C. 实例名[属性名]
- D. 类名[属性名]
答案: A
-
如何调用类的方法?
答案: A
判断题
-
面向对象编程中的类是对象的载体。
答案: 正确
-
类的属性可以在类的外部进行修改。
答案: 错误(类的属性通常在类的内部进行修改)
-
子类继承父类后,父类的方法不能被修改。
答案: 错误(子类可以重写父类的方法)
-
类的继承表示的是底层抽象对高层抽象的继承。
答案: 正确
-
创建类的实例时,必须传递所有初始化参数。
答案: 正确
填空题
-
面向对象编程的核心概念是________,它具有属性和方法。
答案: 对象
-
类的命名推荐使用________命名法。
答案: 驼峰
-
类的属性可以通过________方法进行初始化。
答案: init
-
子类继承父类时,需要在子类的定义中加上________关键字。
答案: super()
-
类的继承表示的是底层抽象对________抽象的继承。
答案: 高层
简答题
-
简述面向对象编程的优点。
答案: 面向对象编程的优点在于它更加符合我们对客观世界的抽象与理解。通过将现实世界中的对象抽象为类,每个类可以包含属性和方法,从而使得代码更加直观、易读、易维护。此外,面向对象编程支持继承、多态等特性,可以减少代码冗余,提高代码的复用性和扩展性。
-
解释类的继承及其应用场景。
答案: 类的继承是指一个类(子类)可以从另一个类(父类)继承属性和方法。通过继承,子类不仅可以使用父类已有的功能,还可以添加新的属性和方法,或者重写父类的方法。继承的应用场景包括:当多个类有共同的属性和方法时,可以通过定义一个父类来提取这些共同特征,从而减少代码冗余;当需要扩展已有类的功能时,可以通过继承并添加新的特性来实现,而不必重新编写整个类。
-
什么是多态?请举例说明。
答案: 多态是指同一个方法在不同类中有不同的实现。例如,假设我们有一个父类
Animal
和两个子类Dog
和Cat
,它们都继承了Animal
类中的make_sound
方法。在Dog
类中,make_sound
方法输出“汪汪”,而在Cat
类中,make_sound
方法输出“喵喵”。当我们调用make_sound
方法时,具体的输出取决于对象的实际类型,这就是多态的体现。 -
简述类的实例化过程。
答案: 类的实例化是指根据类的定义创建具体的对象。具体步骤如下:首先,定义类的名称和属性;其次,通过
__init__
方法初始化类的属性;最后,使用类名加括号并传递必要的初始化参数来创建类的实例。创建的实例可以访问类的属性和方法,从而实现对对象的操作。 -
如何修改类的属性?请给出两种方法。
答案: 修改类的属性有两种常见方法:
- 直接修改:通过实例名.属性名 = 新值 的方式直接修改属性的值。
- 间接修改:通过定义类的方法来修改属性的值,例如定义一个
set_attribute
方法,调用该方法时传递新的属性值,从而实现属性的修改。
题目一:银联信用卡类的定义
根据文中描述,构造一个银联信用卡类 UnionPayCreditCard
,该类应具有如下属性和方法:
-
属性:
- 顾客姓名 (
name
) - 授信额度 (
amount
) - 当前额度 (
current_amount
) - 单次刷卡上限 (
single_limit
)
- 顾客姓名 (
-
方法:
- 获取各属性值的方法 (
get_name
,get_amount
,get_current_amount
,get_single_limit
) - 修改授信额度的方法 (
modify_amount
) - 修改单次刷卡上限的方法 (
modify_single_limit
) - 刷卡方法 (
make_payment
),该方法需检查消费金额是否超过单次刷卡上限及是否有足够额度,若符合条件则扣除相应额度并打印消费信息,否则提示消费失败。
- 获取各属性值的方法 (
答案:
definition 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
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):
temp = self.amount
self.amount = new_amount
print(“你的消费额度已改为:”, new_amount)
return temp
def modify_single_limit(self, new_single_limit):
self.single_limit = new_single_limit
return self.single_limit
def make_payment(self, cost):
if cost <= self.single_limit and cost <= self.current_amount:
self.current_amount -= cost
print(“你本次消费了”, cost, “元,剩余额度应当为”, self.current_amount, “元”)
else:
print(“你的消费金额无法支付,请检查你的信用额度”)
题目二:中国银行信用卡类的定义
基于银联信用卡类,创建一个继承自 UnionPayCreditCard
类的 BOCCreditCard
类,该类新增如下属性和方法:
-
新增属性:
- 积分 (
integral
) - 优惠店铺列表 (
discount_shops
)
- 积分 (
-
新增方法:
- 获取积分的方法 (
get_integral
) - 设置优惠店铺的方法 (
set_discount_shop
) - 重写刷卡方法 (
make_payment
),该方法在特定优惠店铺消费可享受九五折优惠,并获得相应积分,同时打印消费详情,包括优惠金额、获得积分及现有积分总数。
- 获取积分的方法 (
答案:
definition BOCCreditCard(UnionPayCreditCard):
def init(self, name, amount, current_amount, single_limit):
super().init(name, amount, current_amount, single_limit)
self.integral = 0
self.discount_shops = [“ShopA”, “ShopB”]
def get_integral(self):
return self.integral
def set_discount_shop(self, shop_name):
self.discount_shops.append(shop_name)
def make_payment(self, cost, shop_name):
if shop_name in self.discount_shops:
cost = 0.95
self.integral += int(cost * 0.1)
print(“你本次消费”, cost, “元,优惠了”, cost0.05, “元,获得积分”, int(cost*0.1), “分,已有积分”, self.integral, “分”)
super().make_payment(cost)
else:
super().make_payment(cost)