第三次Blog作业
(1)前言:
工作量、难度等的概要性总结
1.Blog作业:博客作业是这学期相对较新奇的作业,以前虽然也有一些总结性的活动但这种想写一遍文章一样反思整个过程的还是挺少见的,作业不多但是我们投入的时间可能因人而异,可能会投入大量时间去思考和反思,但也可能就是完成任务的话也不需要多费力,毕竟这个作业总共也没有布置多少个,所以难度因人而异,对于我自己的话算是中等的吧,要梳理知识点、总结实践心得,锻炼了我们的各方面能力。
2.PTA作业:pta作业总共有11次作业量是最多的,几乎每周都有新的作业,难度要看不同的题目,而且有一些题目是互相关联的,后面的题目会有一些改进,大部分题目难度还行,分阶段递增的。除了第一次的电梯题在算法方面比较难,还要最后一次的题目有一个测试点一直过不了,其他的pta题目的难度都在我的能力范围之内。
3.实验:实验的作业量相对中等,每两周有一个实验作业,总共有5个,因为有专门的课让我们写实验,所以不怎么需要占用我们的其他时间,而且开始的继承多态这种类结构设计难度也不大,自由度很高除了实验指导书上面的一些内容是必须要包含的。但是后面的javafx对于我来说就比较难了,我这部分没有学好,使用 javafx 实现 GUI 界面这种图形化界面的代码写着比较麻烦。
4.线上课程:可以让我们自行安排学习进度,按照自己的节奏进行学习,各个老师讲的也不错能随时回看,适合课余时间补知识点,还有提前预习的作用,从集合框架,到面向对象设计原则,再到十分高效的正则表达式,对我们的学习的有帮助。
5.线下课程:老师可以针对我们的情况相对的讲解,学时比较多,如果有不懂的地方可以找老师答疑;学习难度不大。
(2)面向对象技术总结:
封装、继承、多态的学习
通过许多次的PTA练习,我对于这三个概念已经有了较熟悉的了解;封装是将数据(属性)和操作数据的方法(行为)捆绑在一起,并通过访问控制隐藏内部实现细节的机制。外部对象只能通过公开的接口(如方法)与对象交互,而不需要了解其内部工作原理;继承允许一个类(子类 / 派生类)继承另一个类(父类 / 基类)的属性和方法,从而实现代码复用和层次化设计。子类可以扩展父类的功能,也可以重写父类的方法;多态是指不同类的对象可以通过相同的接口调用,却表现出不同的行为。多态通过继承和方法重写实现,提高了代码的灵活性和可扩展性。
下面我将结合PTA的题目集9的航空货运管理系统中我完成的代码来说明封装、继承、多态的体现
一、封装特性的体现
封装是将数据和操作数据的方法捆绑,并隐藏内部实现细节的机制,在代码中主要通过以下方式实现:
1.属性私有化与方法公开化
所有类的属性均使用private修饰符(如Customer类的customerType、cargo类的weight等),外部无法直接访问
提供公有的 getter/setter 方法作为访问接口,如:
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
2.业务逻辑封装
Cargo类将计费重量计算逻辑封装为独立方法:
public double calculateVolumeWeight(){
return width*height*length/6000;
}
public double getChargeableWeight() {
return Math.max(weight, calculateVolumeWeight());
}
外部只需调用getChargeableWeight()方法,无需关心体积重量计算细节
3.数据隐藏示例
OrderDate类将订单支付方式等敏感信息通过私有属性封装,仅暴露getPaymentMethod()等访问方法
Flight类的maxWeight属性仅允许通过setter方法修改,确保数据合法性
二、继承特性的应用
继承通过子类复用父类代码,实现层次化设计,代码中主要体现在抽象类继承:
1.运费计算模块的继承结构
抽象父类AbsCalculateFreight定义通用接口:
abstract class AbsCalculateFreight{
Cargo cargo;
Customer customer;
abstract double calculateRate(); // 计算费率
abstract double calculateFreight(); // 计算运费
}
子类FreightCalculate继承并实现具体逻辑:
class FreightCalculate extends AbsCalculateFreight{
@Override
public double calculateRate() {
// 根据货物类型和重量计算费率
if(cargo.getCargoType().equals("Normal")){
// 普通货物费率计算逻辑
}
// 其他货物类型处理...
}
@Override
public double calculateFreight() {
// 根据客户类型计算最终运费
if(customer.getCustomerType().equals("Individual")){
return cargo.getChargeableWeight()*calculateRate()*0.9;
}
return cargo.getChargeableWeight()*calculateRate()*0.8;
}
}
2.订单模块的继承设计
抽象类AbsOrder定义订单信息展示接口:
abstract class AbsOrder {
abstract void showCustomerInfo(); // 展示客户信息
abstract void showCargoInfo(); // 展示货物信息
}
Order类继承并实现具体展示逻辑,复用父类属性(flight、cargo等)
3.继承带来的优势
代码复用:FreightCalculate无需重复定义cargo和customer属性
接口统一:所有运费计算类遵循AbsCalculateFreight定义的标准接口
扩展性强:如需新增特殊运费计算方式,只需创建新子类重写方法
三、多态特性的实现
多态使不同对象通过相同接口表现不同行为,在系统中主要体现在:
1.运费计算的多态应用
主程序中通过父类引用调用子类方法:
FreightCalculate freightCalculate=new FreightCalculate(cargo,customer);
freightCalculateList.add(freightCalculate);
计算总运费时无需关心具体货物类型:
double totalFreight=0;
for (int i = 0; i < freightCalculate.size(); i++) {
totalFreight+=freightCalculate.get(i).calculateFreight();
}
不同cargoType(Normal/Expedite)的货物会调用各自的calculateRate()实现
2.订单信息展示的多态
AbsOrder定义的抽象方法在Order类中具体实现:
@Override
public void showCustomerInfo() {
// 个人客户与企业客户共用展示接口,但计算逻辑不同
if(orderDate.getPaymentMethod().equals("Cash")){
System.out.println("现金支付金额:"+totalFreight);
}
// 其他支付方式处理...
}
未来若新增VIPOrder子类,只需重写方法即可适配现有接口
3.多态的实际效果
灵活性:make_animal_speak等价功能的showCustomerInfo方法可处理不同订单类型
可扩展性:新增货物类型时无需修改FreightCalculate调用代码
接口统一:所有运费计算类对外提供相同的calculateFreight()接口
四、三大特性的协同工作
抽象类与接口的学习
| 抽象类 | 接口 | |
|---|---|---|
| 定义关键字 | abstract class | interface |
| 实例化 | 不能直接实例化,需子类继承 | 不能实例化,需类实现 |
| 方法实现 | 可以包含抽象方法和普通方法 | 所有方法都是抽象的(Java 8 + 可加默认方法) |
| 变量 | 可以有成员变量(非静态) | 只能有静态常量(public static final) |
| 继承 / 实现 | 单继承(一个类只能继承一个抽象类) | 多实现(一个类可实现多个接口) |
| 设计理念 | 强调 “所属关系”(is-a) | 强调 “能力 / 行为”(can-do) |
| 代码复用 | 通过普通方法实现复用 | 通过默认方法(Java 8+)实现复用 |
| 构造方法 | 可以有构造方法(供子类调用) | 没有构造方法 |
在航空货运管理系统中的体现
运费计算抽象类(AbsCalculateFreight)
abstract class AbsCalculateFreight{
Cargo cargo;
Customer customer;
public AbsCalculateFreight() {}
public AbsCalculateFreight(Cargo cargo, Customer customer) {
this.cargo = cargo;
this.customer = customer;
}
// 抽象方法:强制子类实现费率计算逻辑
abstract double calculateRate();
// 抽象方法:强制子类实现运费计算逻辑
abstract double calculateFreight();
}
接口的使用在航空货运管理系统我没有用到,我加一个可能的接口
interface Transportable {
double getTransportWeight(); // 获取运输重量
boolean isSuitableForFlight(Flight flight); // 检查是否适合航班运输
}
集合框架的学习
我们最熟悉的就是ArrayList 与 LinkedList了
| 特性 | ArrayList | LinkedList |
|---|---|---|
| 数据结构 | 动态数组 | 双向链表 |
| 查询效率 | O (1)(直接通过索引) | O (n)(从头遍历) |
| 增删效率 | O (n)(需移动元素) | O (1)(仅修改指针) |
| 内存占用 | 连续内存,占用较小 | 离散内存,节点需存储前后指针 |
| 线程安全 | 非线程安全 | 非线程安全 |
还有许多其他的框架
如
Collection 接口体系
List 接口:有序、可重复的集合,元素有明确的索引。
ArrayList:基于数组实现,查询效率高,增删效率低。
LinkedList:基于双向链表实现,增删效率高,查询效率低。
Vector:线程安全的 ArrayList,性能较低(已过时)。
Set 接口:无序、不可重复的集合。
HashSet:基于哈希表实现,插入和查找效率高。
TreeSet:基于红黑树实现,元素有序排列。
LinkedHashSet:维护插入顺序的 HashSet。
Queue 接口:队列,遵循 FIFO(先进先出)原则。
PriorityQueue:优先队列,元素按优先级排序。
LinkedBlockingQueue:线程安全的阻塞队列(用于并发编程)。
2. Map 接口体系
HashMap:基于哈希表实现,键值对存储,查询效率高(JDK8 后引入红黑树优化)。
TreeMap:基于红黑树实现,键有序排列。
LinkedHashMap:维护插入顺序的 HashMap。
Hashtable:线程安全的 HashMap(已过时)。
ConcurrentHashMap:线程安全的高性能 Map(JDK8 后使用 CAS 和分段锁优化)。
但是这些我没怎么用过我打算在c++中有深入了解,用来学算法和数据结构
异常的学习
异常我是在老师的课上了解的,但最开始的接触是在实验中。
异常的基本概念
我目前的学习
try-catch-finally 结构
try {
// 可能抛出异常的代码
} catch (ExceptionType1 e1) {
// 处理ExceptionType1类型的异常
} catch (ExceptionType2 e2) {
// 处理ExceptionType2类型的异常
} finally {
// 无论是否发生异常,都会执行的代码
}
throws 关键字
用于方法声明,表示该方法可能抛出某种异常
语法:public void method() throws ExceptionType
throw 关键字
用于手动抛出异常
语法:throw new ExceptionType("异常信息");
自定义异常
在实际开发中,我们可以自定义异常来满足特定业务需求:
处理流程示例
public void readFile(String filePath) {
FileReader fileReader = null;
try {
fileReader = new FileReader(filePath);
// 读取文件内容
} catch (FileNotFoundException e) {
System.out.println("文件不存在:" + e.getMessage());
} catch (IOException e) {
System.out.println("读取文件出错:" + e.getMessage());
} finally {
// 关闭文件流,释放资源
if (fileReader != null) {
try {
fileReader.close();
} catch (IOException e) {
System.out.println("关闭文件流出错:" + e.getMessage());
}
}
}
}
javafx学习
JavaFX 基本架构组件
Stage(舞台)
JavaFX 应用的顶级容器,类似 Swing 中的 JFrame,负责管理窗口的显示、隐藏和事件。
Scene(场景)
包含所有可视化元素的容器,需关联到 Stage,定义应用的界面内容。
Node(节点)
所有 UI 元素的基类,包括控件(Button、Label 等)、布局容器(Pane、VBox 等)和图形对象。
FXML
基于 XML 的标记语言,用于声明式定义 UI 结构,可通过 FXMLLoader 加载并与控制器类绑定。
Properties(属性)
支持变更通知的特殊数据类型,是数据绑定的基础,如 StringProperty、IntegerProperty。
布局管理器
JavaFX 提供多种布局容器,用于组织界面元素:
Pane:最基础的布局,需手动指定控件坐标。
HBox/VBox:水平 / 垂直排列控件,支持间距和对齐方式。
GridPane:网格布局,将控件放置在指定行列。
BorderPane:分为上、下、左、右、中五个区域。
FlowPane:流式布局,控件按顺序排列,超出边界自动换行。
等等
掌握情况:
我现在对javafx的知识点还不是很熟悉,会在网课上有更多的学习。
采坑心得:
对类设计原则理解不足
改进建议及总结:
1.类的设计最开始要尽可能想全一点,要遵循设计原则,以免后续的业务增加或功能变动导致代码出现太大的变化,可扩展性要好,这两次题目集都有题目是在前一个题目的业务基础上增加其他功能改的,如果最开始类的设计合理就会变动很简单.
2.对于题目的理解不能太基于自己的刻板印象,要尽可能的多思考有没有什么其他的可能,这样可以有效减少之后发现代码问题的难度,这次的重量计算就是很好的例子.
3.在一个方法中不能有if-else多层嵌套,如果有很多中情况可以分成几个方法来处理,太多if-else嵌套会大大提高复杂度.
4.代码注释应尽可能详细,便于之后的维护.
- 增加注释
- :鉴于代码注释量可能不足的情况,在关键方法、复杂逻辑以及类的定义处添加详细注释。注释应说明方法的整体功能、主要逻辑步骤以及参数和返回值的含义,方便自己和他人日后理解和维护代码。
建议

浙公网安备 33010602011771号