bj9

导航

面向对象程序设计———数字电路模拟程序1、2与第一次课堂测验总结

一、前言
数字电路作为处理离散信号的电子电路,以高、低电平对应二进制“1”和“0”,是计算机与各类数字系统的物理实现基础。本次数字电路模拟程序设计通过迭代进阶的方式,逐步引导我们深化对数字电路元件特性、电路连接逻辑、信号传递规则及程序实现逻辑的理解与掌握。以下是各阶段作业的简单总结:

1、数字电路第一次作业
知识点:核心围绕与门、或门、非门、异或门、同或门五种基础逻辑门元件,掌握其输入输出特性;学习元件名与引脚信息的规范表示,理解电路输入、连接信息的解析规则,实现基础逻辑门构成电路的信号计算与输出
题量:属于单核心场景编程题,核心代码集中在元件特性封装、输入信息解析及信号传递与计算模块
难度:难度中等,需准确理解五种基础元件的逻辑规则,清晰梳理输入信息到输出结果的转化流程

2、数字电路第二次作业
知识点:在基础逻辑门基础上,新增三态门、译码器、数据选择器、数据分配器四种元件,需掌握含控制引脚元件的工作机制;完善元件名命名规则,明确含控制引脚元件的引脚排序逻辑;优化程序输出规则,针对不同元件类型制定差异化输出标准,进一步提升程序对复杂电路场景的适配性
题量:属于多元件、多规则协作编程题,需设计多个核心模块封装不同元件特性、解析各类输入信息、处理信号传递逻辑及执行差异化输出,需重点关注各模块间的协调与规则统一
难度:难度较第一次显著增加,若第一次作业代码架构未预留扩展空间,需重构设计以适配新增元件特性与复杂规则,对电路逻辑理解和程序架构设计能力要求更高

二、设计与分析

数字电路第一次作业

    1. 题目要求
      设计数字电路模拟程序,支持与门、或门、非门、异或门、同或门五种基础逻辑门元件的模拟:
      需按照规范解析元件信息,如A(8)1表示 8 输入与门、引脚信息,如A(8)1-2表示对应元件的 2 号引脚;
      处理电路输入信息,如INPUT: A-0 B-1和连接信息,如[A A(8)1-1]表示信号传递;
      遵循元件逻辑规则计算输出:与门全 1 出 1、或门全 0 出 0、非门取反、异或门异出 1、同或门同出 1;
      输出规则:按与 / 或 / 非 / 异或 / 同或的顺序,同类元件按编号排序输出,忽略无有效输入的元件
    1. 类图设计
      faece42327a5fd89c96157b8a43de8f
      Signal 类:封装信号标识与电平数值,是电路中引脚信号传递的基础数据载体
      Gate 类:整合五种基础逻辑门的属性与计算逻辑,是核心业务封装类
    1. 复杂度分析
      c44d22f583507872963d5751f55868c
      8d74553594bb34fef83570857d5203d
      每类方法数:3.8
      每方法平均语句数:7.5
      平均复杂度:3.57
      平均块深度:3.15
      最大方法复杂度:44,出现在main()方法中,该方法需同时处理输入解析、元件初始化、信号传递计算、输出格式化等多流程,逻辑分支与嵌套较多,是复杂度核心点;
      最大块深度:9+,因输入解析和信号传递需多层循环,如遍历连接信息、遍历元件引脚,嵌套层级较深
    1. 题目分析
      本次作业核心是封装基础逻辑门的特性与实现电路信息的解析 - 计算 - 输出流程:
      需将每种逻辑门的输入输出规则抽象为元件类的核心方法,确保不同元件的计算逻辑独立;
      要按规范解析输入的元件、引脚、连接信息,构建元件与引脚的关联关系;
      信号传递需遵循输出引脚可连多输入、输入引脚仅连一个输出的约束,逐引脚传递信号后触发元件计算;
      最终按指定顺序输出元件结果,需对元件进行分类、排序,同时过滤无有效输入的元件

数字电路第二次作业

    1. 题目要求
      在基础逻辑门的基础上,新增三态门、译码器、数据选择器、数据分配器四种元件,同时调整规则:
      元件信息扩展:新增元件的命名规则,如Z(2)2表示 2 控制引脚的数据选择器、引脚排序规则,含控制引脚的元件按 “控制 - 输入 - 输出” 排序;
      异常处理:忽略无有效输入、输入输出断开,如三态门控制端低电平、控制引脚无效的元件输出;
      输出规则差异化:译码器输出输出 0 的引脚编号,数据分配器按引脚顺序输出信号,无效状态用 “-” 表示;
      保留基础逻辑门的逻辑规则与输入连接约束
    1. 类图设计
      495490e7f9b289ab9cf7a645c79f0be
      Gate 抽象类:作为所有门电路父类,统一抽象通用属性与方法,拆分出基础逻辑门、新增扩展元件子类;
点击查看Gate类设计
abstract class Gate {
    protected int number;
    protected int[] pins;
    protected boolean outputCalculated = false;

    public Gate(int number, int pinCount) {
        this.number = number;
        this.pins = new int[pinCount];
        Arrays.fill(pins, -1);
    }

    public abstract void calculateOutput();

    protected abstract boolean isInputValid();

    public abstract String getBaseName();

    public abstract String getOutputName();

    public abstract String getOutputResult();

    public int getNumber() { return number; }

    public void setPin(int pinNum, int value) {
        if (pinNum >= 0 && pinNum < pins.length) {
            pins[pinNum] = value;
        }
    }

    public int getPin(int pinNum) {
        return (pinNum >= 0 && pinNum < pins.length) ? pins[pinNum] : -1;
    }

    public boolean isOutputCalculated() { return outputCalculated; }
    public void resetCalculated() { outputCalculated = false; }
}
    1. 复杂度分析
      b1da84448661d64c4fa110cddbfb9f7
      41f1d8d45e57f5634050dcb013be685
      每类方法数:4.0
      每方法平均语句数:5.2
      平均复杂度:2.62
      平均块深度:2.27
      最大方法复杂度:23,出现在findSignalValue()方法中,该方法需适配新增元件的信号计算规则,但整体平均复杂度(2.62)较第一次显著降低;
      最大块深度:6,虽仍有嵌套,但平均块深度(2.27)降低,代码层级更简洁,新增元件的逻辑被拆分到独立方法中,可读性提升
    1. 题目分析
      本次作业核心是类职责拆分与新增元件的逻辑适配:
      设计上,将原单一元件类拆分为基础逻辑门类、三态门类、译码器类等,每个类仅封装对应元件的特性;新增引脚管理类负责引脚的排序、关联,输出格式化类负责不同元件的差异化输出,符合单一职责原则;
      逻辑上,需实现新增元件的规则:三态门的控制端控制通断、译码器的控制条件 + 编码对应输出、数据选择器的控制端选输入、数据分配器的控制端选输出;
      异常处理需覆盖无效输入、控制无效、连接断开等场景,同时优化输入解析逻辑以适配新增元件的命名与引脚规则;
      对比第一次,代码的模块化程度更高,新增功能的扩展成本降低,整体维护性提升

第一次课堂测验分析
这些题的核心是考查Java基础概念的精准区分,这里我按考点分类梳理:
(1)访问修饰符类
这类题的关键是精准记权限范围+修饰符适用场景,易错点是混淆不同修饰符的边界/适用对象:
protected(2-12、3-3):
正确判断逻辑是protected允许3类访问:同类、同包任意类、不同包子类
权限排序题(2-26):
正确的是public > protected > default > private
顶层类修饰符(3-28):
顶层类仅支持public/默认修饰符,private仅用于内部类
构造方法修饰符(3-38):
仅支持public/protected/private/默认访问修饰符
成员变量修饰符(3-37):
成员变量支持public/private/protected/default/static/final
普通方法修饰符(3-39):
易错点是遗漏abstract/static/final可修饰普通方法,普通方法支持所有访问修饰符+static/final/abstract
封装修饰符(填空):
对属性封装时使用private关键字修饰

(2)构造方法类
核心是构造方法的特殊规则,易错点是把构造方法和普通方法混淆:
2-18、2-28、2-25:
易错点是误选带void的方法,方法名和类名不一致,比如大小写不同的选项,或误以为构造方法可有可无然而类没有显式构造时,系统会默认生成无参构造
3-29:
易错点是误以为构造方法可写void、必须是public,实际构造方法无返回值(不能写void)、修饰符可private/protected等
构造方法调用(填空):
构造方法内通过this(参数)调用本类其他构造方法,子类构造可通过super(参数)调用父类构造

(3)static/this/super类
这类题的关键是区分属于类还是属于对象:
static(2-20、填空):
易错点是把static当成访问修饰符,它是类成员的关键字,不是访问权限修饰符;static修饰成员变量为静态变量(类变量),静态方法不能直接访问实例变量
this/super(2-16、2-17、3-4、填空):
易错点是误以为this/super能在main中用、super能访问父类private成员(private成员super也访问不到);this解决成员变量与局部变量名称冲突,super引用父类成员,二者可在同一构造方法不同行出现
实例变量/类变量(3-32、3-33):
易错点是混淆实例变量(无static、属于对象)和类变量(有static、属于类)的访问规则,比如误以为静态方法能访问实例变量

(4)接口/抽象类类
核心是区分接口和抽象类的本质差异,易错点是概念混淆:
接口相关(2-11、3-1、填空):
易错点是误以为接口所有方法都是抽象方法、接口是类的一种,或认为接口的子类必须重写所有方法(子类为抽象类时可不用);用interface定义接口,implements关键字实现接口
抽象类相关(2-22、3-1):
易错点是误以为抽象类没有构造方法、抽象方法可以写方法体,或在抽象类的类体中直接写执行语句
3-31:
抽象类不能实例化,abstract与final语义冲突
3-23:
实际接口无构造方法,抽象类作为类仅支持单继承

(5)多态类
核心是多态的前提+特性,易错点是遗漏前提条件、混淆多态的优缺点:
3-34:
易错点是误以为向下转型是多态前提,实际多态前提仅需继承、方法重写、父类引用指向子类对象
3-35:
易错点是把父类引用无法访问子类特有成员当成多态好处,实际这是局限性,多态核心好处是可维护性、通用性、扩展性
继承关键字(填空):
extends关键字实现子类继承父类,面向对象三大特性包含多态性

(6)循环/语法规则类
核心是精准记忆Java语法关键字/格式规则,易错点是混淆关键字功能、语法格式错误:
3-30:
循环定义关键字仅for/while,do是while循环的辅助关键字
注释格式(3-17):
仅//、/* /、/* */合法
编译运行命令(填空):
易错点是编译命令书写错误,编译.java文件用javac 文件名.java,运行类用java 类名
标识符/变量定义(3-26、3-25、填空):
易错点是误以为数字开头、含#等特殊字符的标识符合法,或byte可存储超出-128~127范围的数值;int类型占4个字节,布尔常量为true和false
数组定义(3-24、3-27):
二维数组不能仅指定二维长度,数组创建需用[]而非()
循环执行(填空):
需精准分析循环条件、break/continue对循环次数的影响

(7)位运算/字符串类
核心是记忆位运算规则、字符串操作语法,易错点是混淆位运算补位规则、字符串运算符:
3-22:
左移始终补0,右移补符号位,正数补0、负数补1
3-23:
字符串仅支持+拼接,访问字符需用charAt()
字符串类型(填空):
String类型表示不可变字符串

(8)封装类
核心是封装的实现方式+规则,易错点是误以为封装是语法强制要求:
3-21:
封装是规范(private属性+public get/set),不封装也可编译

(9)final/abstract关键字类
核心是记忆关键字语义冲突、适用场景,易错点是混淆关键字组合规则:
3-18:
final可修饰类/方法/属性,二者语义冲突无法共存
final特性(填空):
final修饰变量为常量(仅赋值一次),修饰方法不可被子类重写

(10)异常处理类
核心是异常的抛出与捕获规则,易错点是概念术语混淆:
异常捕获(填空):
异常处理通过捕获特定异常并处理
异常抛出(填空):
易错点是术语错误,程序出错时生成异常类对象的过程称为抛出异常,非抛出错误

(11)包相关类
核心是包的创建与引用规则,易错点是语法格式错误:
包创建(填空):
易错点是语句格式错误,创建包的语句为package 包名;需注意分号、包名小写
包引用(填空):
import关键字引用其他包的类和接口

(12)随机数/顶级父类类
随机数(填空):
通过java.lang.Math类或java.util.Random类获取随机数
顶级父类(填空):
Java所有类的顶级父类是Object

(13)代码执行结果分析类
核心是逐行分析代码逻辑、运算符优先级、变量作用域:
数组遍历计算(填空):
需精准判断条件(如取模、累加规则),计算最终变量值
子类变量覆盖(填空):
子类重名变量不影响父类变量访问,需区分实例变量作用域

三、踩坑心得
两次数字电路模拟程序设计中,最核心的问题是对元件规则、输入输出约束的理解不透彻,以及代码架构未预留扩展空间,导致迭代时大量返工,核心踩坑点如下:

  1. 对题目规则的理解偏差:第一次作业初期未注意输入引脚不能连接多个输出引脚、输出引脚不能短接的约束,仅实现了基础信号计算,调试时发现部分元件信号传递异常,回头重新梳理规则才修正;第二次作业忽略了译码器控制引脚不满足条件时输出全无效的细节,初期按基础门电路逻辑处理,导致输出结果完全不符合要求,反复核对题目后才补全规则判断。由此可见,写代码前需逐字拆解业务规则,明确每个元件的输入、计算、输出约束,避免凭经验臆断规则
  2. 代码架构设计缺陷:第一次作业为快速完成需求,将元件计算、引脚管理、输入解析、输出格式化全部杂糅在 Main 类中,仅用少量方法实现所有逻辑;第二次作业新增三态门、译码器等元件时,原代码无任何拆分和抽象,无法直接扩展,只能推翻重构,浪费大量时间。反思后意识到,迭代开发场景下,前期需先设计类结构,明确各模块职责,而非仅追求功能实现
    类内职责耦合过紧:第一次作业将所有门电路的计算逻辑都写在同一个方法中,通过大量 if-else 区分元件类型;第二次作业初期仍沿用该方式,新增元件后方法逻辑分支暴增,调试时定位问题困难,且修改某类元件的计算规则会影响其他元件,体现出未遵循单一职责原则的弊端
    image
  3. 信号有效性处理遗漏:第二次作业初期未考虑 “三态门高阻态”“译码器控制无效” 等场景下的信号无效状态,按普通 0/1 信号处理,导致输出时未过滤无效元件,与题目要求不符;且代码无注释说明各元件的计算逻辑,迭代时需重新梳理每个分支的含义,调试效率极低

四、改进建议

  • 1.规则拆解与注释规范:
    改进:写代码前先将题目规则拆解为输入解析规则→元件计算规则→输出格式化规则三类,逐条梳理成文档;强制为核心方法添加 Javadoc 注释,明确规则约束和逻辑意图,示例如下:
点击查看代码
/**
 * 计算译码器输出结果
 * @param controlPins 控制引脚电平列表
 * @param inputPins 输入引脚编码列表
 * @return 有效时返回输出0的引脚编号,无效时返回-1
 * @note 仅当S1=1且S2+S3=0时译码器有效,否则输出无效
 */
private int calculateDecoderOutput(List<Integer> controlPins, List<Integer> inputPins) {}
  • 2.架构抽象与接口化设计:
    改进:针对易扩展的核心逻辑抽象接口,拆分不同元件的实现类,避免耦合,示例如下:
点击查看代码
// 抽象门电路接口,定义通用行为
public interface Gate {
    // 校验输入是否有效(含控制引脚、连接完整性)
    boolean isInputValid();
    // 计算输出结果(返回电平/无效标识)
    Object calculateOutput();
}
// 基础逻辑门实现类
public class AndGate implements Gate {}
public class OrGate implements Gate {}
// 新增扩展元件实现类
public class TriStateGate implements Gate {}
public class Decoder implements Gate {}
  • 3.模块拆分与职责单一:
    改进:将代码拆分为输入解析模块InputParser、元件管理模块GateManager、信号计算模块SignalCalculator、输出格式化模块OutputFormatter,每个模块仅负责一类功能;例如 InputParser 专门处理元件、引脚、连接信息的解析,GateManager 专门管理所有元件的初始化和状态维护,降低模块间耦合,便于迭代扩展
  • 4.无效状态统一管理:
    改进:新增 Signal 类的 “有效性标识” 属性valid: boolean,在所有元件计算方法中先校验输入 / 控制有效性,再赋值该标识;输出时统一根据标识过滤无效元件,避免每个输出分支单独判断,简化逻辑

五、总结
1.本阶段核心收获
(1)数字电路编程:掌握 5 种基础逻辑门、4 种扩展元件(三态门 / 译码器等)的工作机制与程序实现,理解电路信息解析 - 计算 - 输出全流程,学会从单一核心场景编程过渡到多元件协作编程,明确模块化、单一职责原则在迭代开发中的重要性
(2)面向对象设计:深化类抽象与继承应用,如 Gate 抽象类拆分子类,理解接口 / 抽象类差异,掌握类职责拆分、模块解耦技巧,降低代码扩展成本
(3)Java 基础巩固:课堂测验的知识点测试让我更加清晰地学习到更多知识。后续复盘中使我对以下知识点掌握更加牢固:精准区分访问修饰符权限、构造方法规则、static/this/super 用法,理清接口与抽象类特性、多态实现前提,熟练掌握异常处理、位运算、数组等基础语法细节
2.需进一步学习及研究的方向
(1)架构设计能力:加强接口化、抽象化设计实践,深入学习设计模式(如工厂模式)在元件创建、管理中的应用,提升代码可扩展性与维护性
(2)规则解析与异常处理:优化复杂输入规则的解析逻辑,研究统一的无效状态处理方案,减少因规则遗漏导致的调试问题
(3)Java 进阶知识:深化多态、继承的实战应用,重点突破抽象类 / 接口的灵活使用场景,加强代码注释规范与文档化编写能力
(4)复杂电路场景适配:探索更复杂数字电路(如组合逻辑电路、时序逻辑电路)的模拟实现,提升程序对多规则、多约束场景的适配能力
3.一些改进建议
提供轻量化类结构示例,引导学生搭建基础架构
发布典型踩坑代码对比,展示错误写法,分析耦合危害与解耦思路
作业前置规则拆解指南,按输入解析 - 信号计算 - 输出过滤拆分任务,标注每步的关键约束,如输入引脚唯一性校验
课上开展作业场景化教学,结合作业中的元件扩展需求,讲解抽象类设计、方法重写等知识点的实际应用
作业周期内设置分阶段答疑,初期答疑聚焦规则理解,中期聚焦架构调试,后期聚焦输出优化

posted on 2025-12-14 00:10  qz9  阅读(3)  评论(0)    收藏  举报