第三次Blog作业:Java的课程总结
一、前言
本学期的Java课程即将结束,在这一学期的学习旅程中,我收获颇丰。从 Blog 作业记录学习心得,到 PTA 平台上不断攻克编程难题;从实验室里的实践操作,再到线上线下课程的知识汲取,每一项学习任务都像是一块块基石,搭建起我对这门学科的认知大厦。回顾这段学习历程,各项学习任务在工作量与难度上各有特点,层层递进。
① Blog作业:第一次Blog作业是对电梯调度题目集的总结,第二次Blog作业是对航空货运管理系统题目集的总结,这次是对整个课程的总结。这几次的Blog作业贯穿整个课程的学习,要求我们定期对所学知识进行梳理、总结,并分享自己的理解与感悟。在这个过程中,不仅锻炼了我的文字表达能力,更促使我深入思考课程内容,对所遇到的困难和不足进行反思,对知识点的把握有了更深的理解。而这几次的Blog是对完成的题目进行反思和总结,要对这一阶段的学习资料进行查找,工作量和难度都不太大。
②PTA作业:侧重于对编程实践能力的提升与考验。每一次作业都围绕课程中的核心知识点展开,题目数量较多,涵盖了从基础语法到复杂工程问题的各种题型,工作量不容小觑。除了一开始的对电梯调度的逻辑分析难度很大以外,其余的作业难度适中,都能够成功做出来。而且PTA采取了迭代的方式,通过对题目的理解和逐步破解,我的编程能力得到了显著提升,认识题目的角度也更加完善,逻辑思维也更加严谨。
③实验:实验环节是将理论知识转化为实际应用的关键途径。从实验环境的搭建,到按照实验步骤进行设计编写思路、编写相应的代码、分析实验结果,整个过程不仅要求我们熟悉理论知识,还考验我们的动手能力和解决实际问题的能力。实验的工作量较大,尤其是在遇到问题需要反复排查和调试时,更是耗时耗力。但是总体难度不大,都是对平常知识的巩固与实践。在这个过程中我学会了如何在实践中发现问题、分析问题并解决问题,加深了我对课程知识的理解和掌握。
④线上及线下课程:本门课程采取了线上和线下相结合的方式,方式新颖,配合得当。线上课程具有丰富的学习资源,没有时间限制,且讲了很多线下没讲的内容,值得我们反复观看与学习。线下老师跳脱传统讲课方式,采用生动形象的例子,帮助我们很好的理解与吸收知识,且讲述了很多书上没有的内容,例如Java的设计模式,让我们对相应的编程思想有了初步的把握。
总的来说,这门课程的各项学习任务相辅相成,让我充分的掌握了Java学习的面向对象编程思想以及几大设计原则的灵活运用,还培养了自主学习、独立思考和解决问题的能力。这些收获不仅可以运用到我的学业上,也对我的生活产生了潜移默化的积极影响。
二、面向对象技术总结
1.封装
封装是面向对象编程的核心原则之一,它将数据(属性)和操作数据的方法绑定在一起,并通过访问修饰符(如private、protected、public)控制外部对这些成员的访问。封装的主要目的是隐藏内部实现细节,提供统一的公共接口,增强代码的安全性和可维护性。例如,在一次PTA雨刷程序功能扩展设计的题目里,要求程序能够根据雨刷系统的类型自动匹配其业务逻辑,两种系统的最大档位不同,因此我设计了一个private的maxPos属性,在不同的系统里通过对其的getter,setter可以设计想要的最大档位。
abstract class Calculate{ private int pos;//档位 private int maxPos;//最大档位 public Calculate(){ } public Calculate(int pos,int maxPos){ this.pos = pos; this.maxPos = maxPos; } public int getPos(){ return pos; } public int getMaxPos(){ return maxPos; } public void Up(){ if(this.pos < maxPos){ this.pos ++; } } public void Down(){ if(this.pos > 1){ this.pos --; } } }
这让我学习到了如何灵活的运用封装保证数据的安全性和扩展,以及后续对数据进行校验和逻辑处理。
2.继承
继承允许一个类(子类)继承另一个类(父类)的属性和方法,从而实现代码复用和层次化设计。在 Java 中,使用extends关键字实现继承,且每个类只能直接继承一个父(单继承),但可以通过接口实现多重继承的效果。例如,PTA航空货运管理系统里,要求输入客户、收件人和发件人的姓名、电话 、地址,于是我抽出一个人物类,用来封装姓名、电话、地址这些个人通用信息,作为Customer、Sender、Receiver类的父类。

通过学习,我能够充分理解继承的特性,在代码复用,代码重写以及IS-A 关系里运用继承,通过创建子类继承父类的属性和方法,减少了大量重复代码的编写,提高了开发效率。在设计具有层次关系的程序结构时,继承能帮助我建立清晰的类层次体系,体现 “is-a” 的关系,使代码逻辑更加直观易懂。
3.多态
多态是同一操作作用于不同对象可以有不同的解释,产生不同的执行结果。多态允许不同类的对象通过相同的接口进行调用,从而实现 "一个接口,多种实现",以通过继承、接口和方法重写实现。例如,在实验三中将大象、老虎、狮子装进电器里,我用父类的Animal 引用指向不同的子类通过调用animal.enterElectric()时会根据实际对象类型执行不同的实现。
// 抽象的动物类 abstract class Animal{ private String name; private double weight; private int enterOrder; private int attackStrength; // 动物类型,默认值为“动物” public String type = "动物"; public Animal(){ } public Animal(String name, double weight, int enterOrder, int attackStrength){ this.name = name; this.weight = weight; this.enterOrder = enterOrder; this.attackStrength = attackStrength; } public String getName(){ return name; } public void setName(String name){ this.name = name; } public double getWeight(){ return weight; } public void setWeight(double weight){ this.weight = weight; } public int getEnterOrder(){ return enterOrder; } public void setEnterOrder(int enterOrder){ this.enterOrder = enterOrder; } public int getAttackStrength(){ return attackStrength; } public void setAttackStrength(int attackStrength){ this.attackStrength = attackStrength; } // 抽象方法:动物进入电器 public abstract void enterElectric(Electric electric); } // 大象类,继承自动物类 class Elephant extends Animal{ public String type = "大象"; public Elephant(String name,double weight, int enterOrder, int attackStrength){ super(name, weight, enterOrder, attackStrength); } //可以运用多态让大象装进冰箱 @Override public void enterElectric(Electric electric){ electric.Open(); int countBefore = electric.getAnimalCount(); electric.addAnimal(this); int countAfter = electric.getAnimalCount(); if(countAfter > countBefore){ System.out.println(getName() + "进入了" + electric.getName() ); }else{ System.out.println(getName() + "没进入" + electric.getName() ); } } } public class Test{ public static void main(String[] args) throws IOException{ File file = new File("input.txt"); int counts = 0; Scanner sc = new Scanner(file); System.out.println("请输入冰箱的名字和容量"); String name = sc.next(); int cap = sc.nextInt(); counts += cap; IceBox iceBox = new IceBox(name, cap,false);//创建冰箱对象,初始状态为关闭 System.out.println("请输入微波炉的名字和容量"); name = sc.next(); cap = sc.nextInt(); counts += cap; // 创建微波炉对象,初始状态为关闭 Microwave microwave = new Microwave(name, cap,false); System.out.println("请输入洗衣机的名字和容量"); name = sc.next(); cap = sc.nextInt(); counts += cap; // 创建洗衣机对象,初始状态为关闭 Washer washing = new Washer(name, cap,false); for(int i = 0; i < counts; i++){ Animal animal = null; // 生成0到2之间的随机数,用于选择动物类型 int r = (int) ((float) Math.random() * 3); // 生成0到1999之间的随机数,作为动物体重 int w = (int) ((float) Math.random() *2000); switch(r){ case 0: animal = new Elephant("大象" + i, w, i, 0); break; case 1: animal = new Lion("狮子" + i, w, i, 1); break; case 2: animal = new Tiger("老虎" + i, w, i, 1); break; } if (animal == null) continue; // 再次生成0到2之间的随机数,用于选择电器 r = (int) ((float) Math.random() *3); switch(r){ case 0: //运用多态装入电器 animal.enterElectric(iceBox); break; case 1: animal.enterElectric(washing); break; case 2: animal.enterElectric(microwave); break; } } Sort sort = new Sort(); iceBox.sortShow(sort); washing.sortShow(sort); microwave.sortShow(sort); } }
这让我学习到了在程序需求发生变化,需要新增或修改功能时,无需大幅改动原有代码,只需创建新的子类并实现相关方法即可,让我理解如何编写更灵活、可扩展的代码,使程序具有良好的可维护性和扩展性。
4.抽象类
抽象类是不能被直接实例化的类,它主要作为其他类的基类,提供公共接口和部分实现。抽象类使用abstract关键字声明,可以包含抽象方法(无实现)和具体方法(有实现)。子类必须实现所有抽象方法才能被实例化。例如,在PTA图形卡片排序游戏里,把Shape设计为抽象类,包含计算面积和判断数据是否符合要求的抽象方法,让不同形状的子根据自身图形的特点,实现相应的面积计算和合法性验证逻辑。
//抽象类Shape abstract class Shape{ private String shapeName; // 构造方法等其他具体方法 public abstract double getArea(); public abstract boolean validate(); @Override public String toString(){ return shapeName; } } //梯形子类 class Trapezoid extends Shape{ private double topSide; private double bottomSide; private double height; // 构造方法和属性访问方法 @Override public double getArea(){ return (topSide + bottomSide) * height / 2; } @Override public boolean validate(){ if(topSide <= 0 || bottomSide <= 0 || height <= 0){ return false; } return true; } }
这让我学会了抽象建模和规范制定。抽象类作为一种模板,定义了子类必须实现的方法,为子类提供了统一的行为规范。在实际开发中,我可以利用抽象类将具有共性的行为抽象出来,确保代码的一致性和规范性。
5.接口
接口是一种完全抽象的类型,它只包含常量和抽象方法的定义,不包含方法实现。类通过implements关键字实现接口,一个类可以实现多个接口,从而弥补单继承的限制。例如,实验四中,定义一个接口“有攻击性“:有一个方法返回0或1,表示该动物是否具有攻击性。
//攻击性接口 interface Aggressive{ int getAttackStyle(); } // 动物抽象类,实现Comparable和Aggressive接口 abstract class Animal implements Comparable<Animal>, Aggressive { private String name; private double weight; private int enterOrder; private int attackStrength; private ArrayList<Animal> eatenAnimals = new ArrayList<> (); public Animal(){ } public Animal(String name, double weight, int enterOrder,int attackStrength){ this.name = name; this.weight = weight; this.enterOrder = enterOrder; this.attackStrength = attackStrength; } public String getName(){ return name; } public void setName(String name){ this.name = name; } public double getWeight(){ return weight; } public void setWeight(double weight){ this.weight = weight; } public int getEnterOrder(){ return enterOrder; } public void setEnterOrder(int enterOrder){ this.enterOrder = enterOrder; } public int getAttackStrength(){ return attackStrength; } public void setAttackStrength(int attackStrength){ this.attackStrength = attackStrength; } public ArrayList<Animal> getEatenAnimals() { return eatenAnimals; } //实现攻击性接口,默认实现返回0 @Override public int getAttackStyle(){ return 0; } //其他方法 } //大象类,继承自Animal类 class Elephant extends Animal{ public Elephant(){ } public Elephant(String name, double weight, int enterOrder, int attackStrength){ super(name, weight, enterOrder, attackStrength); } // 大象攻击方式为非攻击型 @Override public int getAttackStyle(){ return 0; } //继承的其他方法 }
6.集合框架
集合框架提供了一套用于存储和操作数据的接口和类,整个框架围绕几个核心接口构建:List(有序可重复集合,如ArrayList、LinkedList)、Set(无序唯一集合,如HashSet、TreeSet)、Queue(队列,如PriorityQueue)和Map(键值对映射,如HashMap、TreeMap)。其中,ArrayList基于动态数组实现,适合随机访问;LinkedList基于双向链表,适合频繁插入删除;HashMap提供平均O(1)时间复杂度的查找操作。集合框架还包含实用工具类Collections,提供排序、查找、同步化等各种算法操作。例如,在PTA图形卡片分组游戏里,定义了总的卡片集合,以及不同形状的卡片集合,用来对卡片里的数据进行存储和排序。
class DealCardList{ //总的卡片集合 private ArrayList<Card> cardList = new ArrayList<Card>(); //圆形卡片集合 private ArrayList<Card> CircleList = new ArrayList<Card>(); //矩形卡片集合 private ArrayList<Card> RectangleList = new ArrayList<Card>(); //三角形卡片集合 private ArrayList<Card> TriangleList = new ArrayList<Card>(); //梯形卡片集合 private ArrayList<Card> TrapezoidList = new ArrayList<Card>(); public DealCardList(){ } public DealCardList(ArrayList<Integer> list){ Scanner sc = Main.input; // 使用Main中的静态Scanner for(int i = 0; i < list.size(); i++) { int shapeType = list.get(i); Shape shape = null; switch(shapeType){ case 1: double radius = sc.nextDouble(); shape = new Circle(radius); CircleList.add(new Card(shape)); break; case 2: double width = sc.nextDouble(); double length = sc.nextDouble(); shape = new Rectangle(width, length); RectangleList.add(new Card(shape)); break; case 3: double side1 = sc.nextDouble(); double side2 = sc.nextDouble(); double side3 = sc.nextDouble(); shape = new Triangle(side1, side2, side3); TriangleList.add(new Card(shape)); break; case 4: double topSide = sc.nextDouble(); double bottomSide = sc.nextDouble(); double height = sc.nextDouble(); shape = new Trapezoid(topSide, bottomSide, height); TrapezoidList.add(new Card(shape)); break; } cardList.add(new Card(shape)); } } public boolean validate(){ for(int i = 0; i < cardList.size(); i++){ Card card = cardList.get(i); if(!card.getShape().validate()){ return false; } } return true; } //对不同种类的集合进行排序 public void cardSort(ArrayList<Card> list){ Collections.sort(list); } //求不同集合里的面积和 public double getAllArea(ArrayList<Card> list){ double sum = 0; for(int i = 0; i < list.size(); i++){ Card card = list.get(i); sum += card.getShape().getArea(); } return sum; } //其他方法 }
这让我学会了处理和存储数据的能力。集合框架提供了丰富的接口和类,适用于各种不同的数据存储和操作场景。从简单的列表、集合到复杂的映射结构,我学会了根据具体需求选择合适的集合类型,高效地进行数据的增删改查操作。但是,对于Set和Map接口,我还没有充分掌握,尽管知道有些场合使用这两个能更高效的解决问题,但因为缺乏熟练的运用,往往采取了另一种复杂的方法,今后我会加强对这几个接口的深入学习,做到简单高效的解决问题。
7.异常
异常是Java处理程序运行时错误的机制,分为检查型异常(如IOException,必须处理)和运行时异常(如NullPointerException,可选择性处理)。通过try-catch-finally结构,程序能捕获和处理异常,避免意外崩溃。例如,PTA统计Java程序中关键词的出现次数里,运用了异常处理机制,当未输入源码时,程序不会崩溃停止,而是捕获和处理错误。
public class Main{ public static void main(String[] args){ Scanner sc = new Scanner(System.in); //运用try-catch来捕获未输入源码时的异常情况 try{ sc.useDelimiter("\\Z"); String longText = sc.next(); if(longText.equals("exit") || longText.isEmpty()){ System.out.println("Wrong Format"); }else{ ArrayList<String> list = new ArrayList<>(); list.add("abstract"); list.add("assert"); list.add("boolean"); list.add("break"); list.add("byte"); list.add("case"); list.add("catch"); list.add("char"); list.add("class"); list.add("continue"); list.add("default"); list.add("do"); list.add("double"); list.add("else"); list.add("enum"); list.add("extends"); list.add("final"); list.add("finally"); list.add("float"); list.add("for"); list.add("if"); list.add("implements"); list.add("import"); list.add("int"); list.add("interface"); list.add("instanceof"); list.add("long"); list.add("native"); list.add("new"); list.add("package"); list.add("private"); list.add("protected"); list.add("public"); list.add("return"); list.add("short"); list.add("static"); list.add("strictfp"); list.add("super"); list.add("switch"); list.add("synchronized"); list.add("this"); list.add("throw"); list.add("throws"); list.add("transient"); list.add("try"); list.add("void"); list.add("volatile"); list.add("while"); list.add("goto"); list.add("const"); list.add("true"); list.add("false"); list.add("null"); dealWith processor = new dealWith(); processor.setList(list); ArrayList<String> newList1 = processor.check(longText); ArrayList<Integer> newList2 = processor.contain(longText, newList1); ArrayList<KeyWordCount> results = new ArrayList<>(); for (int i = 0; i < newList1.size(); i++) { results.add(new KeyWordCount(newList1.get(i), newList2.get(i))); } Collections.sort(results); for(int i = 0; i < results.size(); i++){ KeyWordCount result = results.get(i); System.out.printf("%d\t%s\n", result.getCount(), result.getKeyWord()); } } }catch (Exception e) { System.out.println("Wrong Format"); } } }
这让我学会了如何构建健壮可靠的程序。通过使用try-catch-finally语句块,我能够捕获和处理程序运行时可能出现的各种错误,避免程序因异常而崩溃,提高了程序的容错性和稳定性。
8.JavaFX
JavaFX 是 Java 的官方 GUI(图形用户界面)框架,用于构建跨平台的桌面和移动端应用程序,支持响应式布局和事件驱动编程。例如,第五次实验里,运用了Button、ListView 等组件搭建电器与动物选择界面,利用鼠标点击事件监听和 Lambda 表达式实现电器与动物的交互选择,用JavaFx简单做了一个把动物装进电器的可视化界面。

这让我学会了图形界面开发的基本技能。从创建简单的窗口和控件,到使用布局管理器设计复杂的界面布局,我学会了运用 JavaFX 构建简单的用户界面。JavaFx的内容非常丰富,且这部分的学习通过翻转课堂实现的,对于一些复杂的内容没能完全掌握,需要进一步的了解和探索。
三、踩坑心得
弯路:
通过本学期的Java课程学习,我系统掌握了面向对象编程的核心思想与设计原则,包括封装、继承、多态三大特性,以及抽象类、接口、集合框架等关键技术。在实践过程中,我深刻体会到单一职责、开闭原则、里氏替换等设计原则的重要性,并学会了运用这些原则构建更健壮、可扩展的代码结构。课程通过Blog反思、PTA编程、实验操作等多元化的学习方式,培养了我的问题分析能力、编程实践能力和系统设计思维。特别是JavaFX的学习让我初步掌握了现代GUI开发技术,而异常处理机制则强化了我的防御性编程意识。建议未来课程可以适当增加实际案例的讲解,帮助更好地理解面向对象思想在复杂系统中的应用。总体而言,这门课程不仅让我掌握了Java编程技能,更重要的是培养了我用面向对象思维方式分析和解决问题的能力,为后续的软件开发学习奠定了坚实基础。

浙公网安备 33010602011771号