面向对象编程习题
(1)两大编程思想
习题 1.1 (面向过程)
编写一个面向过程的程序,计算并打印一个列表中所有偶数的和。
○ 定义一个列表 numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
。
○ 定义一个函数 sum_even_numbers(num_list)
,接收列表作为参数,计算偶数和并返回。
○ 调用函数并打印结果。
参考:
1
2
3
4
5
6
7
8
9
10
# 计算并打印一个列表中所有偶数的和
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def sum_even_numbers(num_list):
sum = 0
for n in num_list:
if n % 2 == 0:
sum += n
return sum
res1 = sum_even_numbers(numbers)
print(f"{numbers}中所有偶数的和是:{res1}")
习题 1.2 (面向对象)
将习题1.1中的功能改写为面向对象的方式。
○ 定义一个 NumberProcessor 类。
○ 在 init 方法中接收一个数字列表作为实例属性。
○ 定义一个 sum_even_numbers
方法,该方法不接收额外参数,而是使用实例属性中的列表来计算偶数和并返回。
○ 创建 NumberProcessor 对象,并调用其方法。
参考:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class NumberProcessor:
def __init__(self, num_list):
self.num_list = num_list
print(f"对象已创建,初始数字列表是:{self.num_list}")
def sum_even_numbers(self):
sum = 0
for n in self.num_list:
if n % 2 == 0:
sum += n
return sum
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12]
np = NumberProcessor(numbers)
res2 = np.sum_even_numbers()
print(f"{np.num_list}中所有偶数的和是:{res2}")
(2)类和对象的创建
习题 2.1
创建一个 Book 类,包含 title (书名) 和 author (作者) 两个实例属性。
○ 在 init 方法中初始化这两个属性。
○ 添加一个 display_info
方法,打印书名和作者信息。
○ 创建两个 Book 对象,并调用它们的 display_info
方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
print(f"由{self.author}写的《{self.title}》书被创建了")
def display_info(self):
print(f"信息:由{self.author}写的《{self.title}》书")
book1 = Book("计算机网络", "James F. Kurose, Keith W. Ross")
book2 = Book("TCP/IP 详解", "W. Richard Stevens")
book1.display_info()
book2.display_info()
习题 2.2
创建一个 Car 类,包含 make (品牌), model (型号) 和 year (年份) 三个实例属性。
○ 在 init 方法中初始化这些属性。
○ 添加一个 start_engine
方法,打印 "[make] [model] engine started."
。
○ 创建一个 Car 对象,并调用其 start_engine
方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Car:
def __init__(self, make, model, year):
'''
make: 品牌
model: 型号
year: 年份
'''
self.make = make
self.model = model
self.year = year
def start_engine(self):
print(f"[{self.make}][{self.model}] 发动机启动了!")
car1 = Car("Honda", "Civic Sedan Sport Touring Hybrid", 2025)
car1.start_engine()
(3)类对象和类属性
习题 3.1
创建一个 Student 类,包含以下属性:
○ 一个类属性 school_name
,默认值为 “High School A”。
○ 一个类属性 student_count
,用于记录创建了多少个学生实例。
○ 实例属性 name 和 age。
○ 在 init 方法中初始化实例属性,并确保 student_count
正确递增。
○ 添加一个 get_info
方法,打印学生的姓名、年龄和学校名称。
○ 创建两个 Student 对象,打印它们的 get_info
,然后打印 Student.student_count
。
参考:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Student:
school_name = "High School A"
student_count = 0 # 记录创建了多少个学生实例
def __init__(self, name, age): # 实例属性 name 和 age
self.name = name
self.age = age
Student.student_count += 1
def get_info(self):
# 打印学生的姓名、年龄和学校名称
print(f"学生姓名:{self.name}, 学生年龄:{self.age}, 学校名称:{self.school_name}")
# 创建两个 Student 对象,打印它们的 `get_info`,然后打印 `Student.student_count`。
s1 = Student("Adele", 16)
print(f"Student.student_count:{Student.student_count}")
s2 = Student("Bob", 18)
print(f"Student.student_count:{Student.student_count}")
s1.get_info()
s2.get_info()
习题 3.2
在习题3.1的基础上,演示类属性的“遮蔽”现象。
○ 创建一个新的 Student 实例 student3。
○ 通过 student3 实例修改其 school_name
为 “University B”。
○ 打印 student3.get_info()
。
○ 打印 Student.school_name
和之前创建的 student1.get_info()
,观察它们是否受到影响。
1
2
3
4
student3.school_name = "University B"
student3.get_info()
print(f"Student.school_name:{Student.school_name}")
s1.get_info()
(4)类方法与静态方法
习题 4.1
创建一个 Circle 类,包含以下内容:
○ 一个类属性 PI,值为 3.14159。
○ 一个实例属性 radius (半径)。
○ 一个实例方法 calculate_area
,计算并返回圆的面积。
○ 一个类方法 from_diameter
,接收直径作为参数,并返回一个 Circle 实例。
○ 一个静态方法 is_valid_radius
,接收一个数字作为参数,判断它是否是有效的半径(大于0)。
○ 创建两个 Circle 对象:一个通过 init 创建,一个通过 from_diameter
创建。
○ 调用它们的 calculate_area
方法。
○ 使用 is_valid_radius
验证一些半径值。
参考:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Circle:
# 类属性 PI,值为 3.14159。
PI = 3.1415926
# 实例属性 radius (半径)。
def __init__(self, radius):
self.radius = radius
# 实例方法 calculate_area,计算并返回圆的面积。
def calculate_area(self):
return Circle.PI * self.radius * self.radius
# 类方法 from_diameter,接收直径作为参数,并返回一个 Circle 实例。
@classmethod
def from_diameter(cls, diameter):
return cls(diameter / 2)
# 静态方法 is_valid_radius,接收一个数字作为参数,判断它是否是有效的半径(大于0)
@staticmethod
def is_valid_radius(arg):
return arg > 0
c1 = Circle(3)
c2 = Circle.from_diameter(6)
print(f"c1的半径是:{c1.radius}, 面积是:{c1.calculate_area()}")
print(f"c2的半径是:{c2.radius}, 面积是:{c2.calculate_area()}")
print(Circle.is_valid_radius(9))
print(Circle.is_valid_radius(-1))
习题 4.2
创建一个 Logger 类,用于记录日志。
○ 一个类属性 log_level
,默认值为 “INFO”。
○ 一个类方法 set_log_level(cls, level)
,用于修改 log_level
。
○ 一个静态方法 format_message(message)
,接收一个字符串,返回格式化后的消息(例如,”[TIMESTAMP] - MESSAGE”)。
○ 一个实例方法 log(self, message)
,根据当前的 log_level 打印消息(例如,如果 log_level
是 “INFO”,则打印所有消息;如果是 “ERROR”,则只打印错误消息)。
○ 创建 Logger 实例,测试不同日志级别下的消息打印。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from datetime import datetime
class Logger:
# 类属性 log_level,默认值为 "INFO"。
log_level = "INFO"
# 类方法 set_log_level(cls, level),用于修改 log_level。
@classmethod
def set_log_level(cls, level):
Logger.log_level = level
# 静态方法 format_message(message),接收一个字符串,返回格式化后的消息(例如,"[TIMESTAMP] - MESSAGE")。
@staticmethod
def format_message(message):
formatted_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print(f"[{formatted_time}]-{message}")
# 实例方法 `log(self, message)`,根据当前的 log_level 打印消息
# (例如,如果` log_level `是 "INFO",则打印所有消息;如果是 "ERROR",则只打印错误消息)。
def log(self, message):
if Logger.log_level == "INFO":
print(message)
elif Logger.log_level == "ERROR":
print(f"错误消息:{message}")
logger = Logger()
logger.format_message("设备状态良好")
logger.set_log_level("ERROR")
logger.log("设备需重启,回滚")
logger.format_message("设备已回滚")