一实验目的
l 使学生掌握Python下类与对象的基本应用;
l 使学生掌握Python下继承与多态的基本应用;
l 使学生掌握Python接口的基本应用;
l 使学生掌握Python异常处理的基本应用;
二实验环境及实验准备
l 所需软件环境为Pyhton 3.x等;
l 掌握Python下类与对象、继承与多态的基本概念与应用;
l 掌握Python下接口的基本概念与应用;
l 掌握Python下异常处理的基本概念与应用
三实验内容
(一)、设计高校人员信息包,并完成测试
【题目描述】定义一个人员类People,其属性有:姓名、性别、年龄;基于People实现学生类Student,添加属性:学号、入学时间和入学成绩;基于People实现教师类Teacher,添加属性:职务、部门、工作时间;基于Student实现究生类Graduate,添加属性:研究方向和导师,分别定义其中的构造函数和输出函数。程序中定义各种类的对象,并完成测试。 基于以上类利用接口实现在职研究生类 GradOnWork。
【源代码程序】
class People:
def __init__(self, name, gender, age):
self.name = name
self.gender = gender
self.age = age
def display_info(self):
print(f"姓名: {self.name}, 性别: {self.gender}, 年龄: {self.age}")
class Student(People):
def __init__(self, name, gender, age, student_id, enrollment_year, admission_score):
super().__init__(name, gender, age)
self.student_id = student_id
self.enrollment_year = enrollment_year
self.admission_score = admission_score
def display_student_info(self):
super().display_info()
print(f"学号: {self.student_id}, 入学年份: {self.enrollment_year}, 录取分数: {self.admission_score}")
class Teacher(People):
def __init__(self, name, gender, age, title, department, working_years):
super().__init__(name, gender, age)
self.title = title
self.department = department
self.working_years = working_years
def display_teacher_info(self):
super().display_info()
print(f"职务: {self.title}, 部门: {self.department}, 工作时间: {self.working_years}")
class Graduate(Student):
def __init__(self, name, gender, age, student_id, enrollment_year, admission_score, research_direction, advisor):
super().__init__(name, gender, age, student_id, enrollment_year, admission_score)
self.research_direction = research_direction
self.advisor = advisor
def display_graduate_info(self):
super().display_student_info()
print(f"研究方向: {self.research_direction}, 导师: {self.advisor}")
class GradOnWork(Graduate):
def __init__(self, name, gender, age, student_id, enrollment_year, admission_score, research_direction, advisor, work_status):
super().__init__(name, gender, age, student_id, enrollment_year, admission_score, research_direction, advisor)
self.work_status = work_status
def display_work_status(self):
print(f"工作状态: {self.work_status}")
# 重写显示信息方法,包含工作状态
def display_graduate_info(self):
super().display_graduate_info()
self.display_work_status()
if __name__ == "__main__":
# 创建一个研究生实例
grad_student = Graduate("索尔古德曼", "男", 24, "S2023001", 2023, 85.0, "文科", "Dr.布吉岛")
grad_student.display_graduate_info()
# 创建一个在职研究生实例
grad_on_work = GradOnWork("沃尔特怀特", "男", 27, "S2021002", 2021, 90.0, "结晶学", "Prof.海森堡", "在职研究生")
grad_on_work.display_graduate_info()
【运行测试】
(二)、以圆类为基础设计三维图形体系
【题目描述】设计三维图形类体系,要求如下:
设计三维图形功能接口,接口包含周长、面积、体积计算方法;
基于以上接口,首先定义点类,应包含x,y坐标数据成员,坐标获取及设置方法、显示方法等;
以点类为基类派生圆类,增加表示半径的数据成员,半径获取及设置方法,重载显示函数,并可计算周长和面积等;
以圆类为基础派生球类、圆柱类、圆锥类;要求派生类球、圆柱、圆锥中都含有输入和输出显示方法;并可计算面积、周长。
程序中定义各种类的对象,并完成测试。
【源代码程序】
from abc import ABC, abstractmethod
class ThreeDShapeInterface(ABC):
@abstractmethod
def perimeter(self):
pass
@abstractmethod
def area(self):
pass
@abstractmethod
def volume(self):
pass
class Point:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def get_coordinates(self):
return self.x, self.y
def set_coordinates(self, x, y):
self.x = x
self.y = y
def display(self):
print(f"坐标: ({self.x}, {self.y})")
import math
def base_area(radius):
"""
计算圆的面积
参数:
radius: 圆的半径
返回:
圆的面积
"""
area = math.pi * (radius ** 2)
return area
class Circle(Point, ThreeDShapeInterface):
def __init__(self, x=0, y=0, radius=1):
super().__init__(x, y)
self.radius = radius
def get_radius(self):
return self.radius
def set_radius(self, radius):
self.radius = radius
def display(self):
super().display()
print(f"半径: {self.radius}")
def perimeter(self):
return 2 * math.pi * self.radius
def area(self):
return math.pi * self.radius ** 2
# 圆作为二维图形,没有体积
def volume(self):
raise NotImplementedError("ERROR")
class Sphere(Circle):
def __init__(self, x=0, y=0, radius=1):
super().__init__(x, y, radius)
def volume(self):
return 4/3 * math.pi * self.radius ** 3
class Cylinder(Circle):
def __init__(self, x=0, y=0, radius=1, height=1):
super().__init__(x, y, radius)
self.height = height
def get_height(self):
return self.height
def set_height(self, height):
self.height = height
def display(self):
super().display()
print(f"高: {self.height}")
def area(self):
base_area = super().area()
side_area = 2 * math.pi * self.radius * self.height
return 2 * base_area + side_area
def volume(self):
return base_area * self.height
class Cone(Circle):
def __init__(self, x=0, y=0, radius=1, height=1):
super().__init__(x, y, radius)
self.height = height
def get_height(self):
return self.height
def set_height(self, height):
self.height = height
def display(self):
super().display()
print(f"高: {self.height}")
def area(self):
base_area = super().area()
slant_height = math.sqrt(self.radius**2 + self.height**2)
side_area = math.pi * self.radius * slant_height
return base_area + side_area
def volume(self):
return 1/3 * base_area * self.height
point = Point(3, 4)
point.display()
circle = Circle(0, 0, 5)
circle.display()
print(f"周长: {circle.perimeter()}, 面积: {circle.area()}")
sphere = Sphere(1, 2, 3)
sphere.display()
print(f"体积: {sphere.volume()}")
cylinder = Cylinder(0, 0, 4, 6)
cylinder.display()
print(f"面积: {cylinder.area()}, 体积: {cylinder.volume()}")
cone = Cone(0, 0, 4, 6)
cone.display()
print(f"面积: {cone.area()}, 体积: {cone.volume()}")
【运行测试】
(三)、设计并实现计算不同职称的教师工资
【题目描述】设计教师接口,该接口包含教师工资计算方法。应用(一)中的高校人员信息包,设计不同职称的教师类:教授,副教授,讲师,教师的基本信息包括姓名、性别、出生年月、职称、课时工作量等属性。注意学校对教师每月工资的计算规定如下:固定工资+课时补贴;教授的固定工资为5000元,每个课时补贴50元;副教授的固定工资为3000元,每个课时补贴30元;讲师的固定工资为2000元,每个课时补贴20元。
程序中定义各种教师类的对象,并编写程序求这些教师的月工资。
【源代码程序】
from abc import ABC, abstractmethod
class Teacher(ABC):
def __init__(self, name, gender, birth_date, title, hours_worked):
self.name = name
self.gender = gender
self.birth_date = birth_date
self.title = title
self.hours_worked = hours_worked
@abstractmethod
def calculate_monthly_salary(self):
pass
class Professor(Teacher):
def __init__(self, name, gender, birth_date, hours_worked):
super().__init__(name, gender, birth_date, '教授', hours_worked)
def calculate_monthly_salary(self):
base_salary = 5000
hourly_rate = 50
return base_salary + (self.hours_worked * hourly_rate)
class AssociateProfessor(Teacher):
def __init__(self, name, gender, birth_date, hours_worked):
super().__init__(name, gender, birth_date, '副教授', hours_worked)
def calculate_monthly_salary(self):
base_salary = 3000
hourly_rate = 30
return base_salary + (self.hours_worked * hourly_rate)
class Lecturer(Teacher):
def __init__(self, name, gender, birth_date, hours_worked):
super().__init__(name, gender, birth_date, '讲师', hours_worked)
def calculate_monthly_salary(self):
base_salary = 2000
hourly_rate = 20
return base_salary + (self.hours_worked * hourly_rate)
def main():
prof_li = Professor('詹姆斯—摩根—麦吉尔', '男', '1970-01-01', 120)
assoc_prof_wang = AssociateProfessor('杰西—平克曼', '女', '1975-05-10', 100)
lect_zhang = Lecturer('索尔—古德曼', '男', '1980-08-20', 150)
print(f"{prof_li.name} 的月工资为:{prof_li.calculate_monthly_salary()}元")
print(f"{assoc_prof_wang.name} 的月工资为:{assoc_prof_wang.calculate_monthly_salary()}元")
print(f"{lect_zhang.name} 的月工资为:{lect_zhang.calculate_monthly_salary()}元")
if __name__ == "__main__":
main()
【运行测试】
(四)、设计异常处理类Cexception,并基于异常处理类设计并实现日期类Date
【题目描述】
【题目描述】
定义一个异常类Cexception解决日期类实现中的自定义异常处理。设计的日期类应包含以下内容:
① 有三个成员数据:年、月、日;
② 有设置日期的成员函数;
③ 有用格式"月/日/年"输出日期的成员函数;
④ 要求在日期设置及有参构造函数中添加异常处理。
【源代码程序】
class CException(Exception):
"""自定义日期相关的异常类"""
def __init__(self, message):
super().__init__(message)
class Date:
def __init__(self, year_input=None, month_input=None, day_input=None):
if year_input is None or month_input is None or day_input is None:
self.prompt_and_set_date()
else:
try:
self.set_year(year_input)
self.set_month(month_input)
self.set_day(day_input)
except CException as e:
print(f"错误:{e}")
def prompt_and_set_date(self):
while True:
try:
year = int(input("请输入年份: "))
month = int(input("请输入月份: "))
day = int(input("请输入日期: "))
self.set_year(year)
self.set_month(month)
self.set_day(day)
break # 成功设置日期后退出循环
except ValueError:
print("输入无效,请确保输入的是整数。")
except CException as e:
print(f"错误:{e}")
def set_year(self, year):
if year < 1:
raise CException("年份不是正整数。")
self.year = year
def set_month(self, month):
if not (1 <= month <= 12):
raise CException("月份错误。")
self.month = month
def set_day(self, day):
if not (1 <= day <= self.get_max_day()):
raise CException("日期范围错误")
self.day = day
def get_max_day(self):
if self.month == 2:
if self.is_leap_year():
return 29
else:
return 28
elif self.month in [4, 6, 9, 11]:
return 30
else:
return 31
def is_leap_year(self):
return (self.year % 4 == 0 and self.year % 100 != 0) or (self.year % 400 == 0)
def display(self):
return f"{self.month}/{self.day}/{self.year}"
# 程序测试 - 通过控制台输入
print("请输入日期(或输入错误的日期以测试异常处理):")
date = Date()
print(f"设置的日期为: {date.display()}")
【运行测试】
(五)、设计并实现平面点类Point
【题目描述】
定义一个平面点类Point,对其重载运算符关系运算符,关系运算以距离坐标原点的远近作为基准,远的为大。程序完成对其的测试。
【源代码程序】
import math
class Point:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def distance_from_origin(self):
"""计算点到原点的距离"""
return math.sqrt(self.x ** 2 + self.y ** 2)
def __lt__(self, other):
"""小于运算符重载:判断当前点距离原点是否比另一个点更近"""
return self.distance_from_origin() < other.distance_from_origin()
def __gt__(self, other):
"""大于运算符重载:判断当前点距离原点是否比另一个点更远"""
return self.distance_from_origin() > other.distance_from_origin()
def __le__(self, other):
"""小于等于运算符重载"""
return self.distance_from_origin() <= other.distance_from_origin()
def __ge__(self, other):
"""大于等于运算符重载"""
return self.distance_from_origin() >= other.distance_from_origin()
def main():
points = []
for i in range(3):
while True: # 循环直到获得有效输入
try:
print(f"请输入第{i+1}个点的坐标,格式为 'x y':")
coords = input().strip().split()
if len(coords) != 2 or not all(coord.isdigit() for coord in coords):
raise ValueError("输入格式错误,请确保输入为两个整数,用空格分隔。")
points.append(Point(int(coords[0]), int(coords[1])))
break # 成功则跳出循环
except ValueError as e:
print(f"发生错误:{e} 请重新输入。")
# 确保至少有三个点后进行后续操作
if len(points) == 3:
# 比较并打印结果
print(f"点的坐标从原点出发的远近顺序为:")
for point in sorted(points, key=lambda p: p.distance_from_origin(), reverse=True):
print(f"({point.x}, {point.y})", end=' ')
print("\n")
# 示例比较
print(f"点1与点2的比较:")
print("点1 > 点2" if points[0] > points[1] else "点1 <= 点2")
else:
print("未正确输入所有三个点的坐标。")
if __name__ == "__main__":
main()
【运行测试】
四实验分析及问题思考
结合实例,比较Python与Java在类的定义、继承、多态等方面的异同,总结Python面向对象程序设计中的原则和注意事项。
【答案】类的定义
Python: Python中定义类非常简洁,不需要关键字public、private来修饰成员变量或方法,默认都是公开的。可以使用双下划线__前缀来实现一定程度的私有化。
Python
1class MyClass:
2 def __init__(self, value):
3 self.value = value
4
5 def show_value(self):
6 print(self.value)
Java: Java中类的定义更为严格,成员变量和方法默认访问权限是包内可见(没有修饰符时),需要明确使用public、private、protected等修饰符来控制访问权限。
Java
1public class MyClass {
2 private int value;
3
4 public MyClass(int value) {
5 this.value = value;
6 }
7
8 public void showValue() {
9 System.out.println(this.value);
10 }
11}
继承
Python: Python支持单继承或多继承,语法上只需在类名后跟上父类名即可,使用super()调用父类方法。
Python
1class MyDerivedClass(MyClass):
2 def __init__(self, value, name):
3 super().__init__(value)
4 self.name = name
Java: Java同样支持单继承和接口的多重实现,但不支持多继承(除了实现多个接口)。使用super关键字调用父类构造器或方法。
Java
1public class MyDerivedClass extends MyClass {
2 private String name;
3
4 public MyDerivedClass(int value, String name) {
5 super(value);
6 this.name = name;
7 }
8}
标签:__,name,self,init,print,def,5.28 From: https://www.cnblogs.com/szm123/p/18257047