
在uml类图中,构造器通常被表示为一个操作(operation),其名称与类名相同,并且根据uml规范,应带有 «create» 构造型(stereotype)并返回该类的一个实例,例如 + «create» student(name:string):student。然而,在实际应用中,许多开发者会遵循主流面向对象语言(如java)的约定,将与类同名且未明确指定返回类型的操作视为构造器,例如 student(name:string)。
在Java中实现一个构造器,其方法名必须与类名完全一致,且没有返回类型(包括 void)。根据UUML图中的 Student(name:String) 约定,其Java实现应如下:
public class Student {
private String name;
// ... 其他属性
public Student(String name) {
this.name = name;
// ... 其他属性的初始化
}
// ... 其他方法
}根据需求,每个学生需要一个包含6个作业分数的数组和一个包含3个考试分数的数组,且初始时为空。在Java构造器中,我们可以使用 new 关键字来初始化这些数组,并为它们分配默认的内存空间。对于 int 类型的数组,元素将自动初始化为 0。
public class Student {
private String name;
private int[] homeworkScores; // 存储作业分数,6个
private int[] examScores; // 存储考试分数,3个
public Student(String name) {
this.name = name;
this.homeworkScores = new int[6]; // 初始化为6个元素的数组,默认值为0
this.examScores = new int[3]; // 初始化为3个元素的数组,默认值为0
}
// ... 其他方法
}为了使 Student 类功能完善,我们需要实现计算作业平均分和最终成绩的方法。
此方法需要遍历 homeworkScores 数组,累加所有分数,然后除以作业数量。
立即学习“Java免费学习笔记(深入)”;
public double getHomeworkAverage() {
if (homeworkScores == null || homeworkScores.length == 0) {
return 0.0; // 避免除以零或空数组的情况
}
int sum = 0;
for (int score : homeworkScores) {
sum += score;
}
return (double) sum / homeworkScores.length;
}最终成绩的计算规则为:考试1占15%,考试2占25%,考试3占30%,作业平均分占30%。
public double getFinalScore() {
// 确保考试分数数组有足够的元素
if (examScores == null || examScores.length < 3) {
// 可以选择抛出异常或返回一个错误值,这里返回0.0作为示例
return 0.0;
}
double exam1Weight = 0.15;
double exam2Weight = 0.25;
double exam3Weight = 0.30;
double homeworkWeight = 0.30;
double finalScore = (examScores[0] * exam1Weight) +
(examScores[1] * exam2Weight) +
(examScores[2] * exam3Weight) +
(getHomeworkAverage() * homeworkWeight);
return finalScore;
}在Java中,直接通过getter方法返回数组引用,或者通过setter方法直接接收并赋值数组引用,存在潜在的安全风险。外部代码可以通过获得的数组引用直接修改对象的内部状态,从而破坏封装性。
例如:
// 假设 Student student = new Student("Alice");
int[] scores = student.getHomeworkScores(); // 获取内部数组引用
scores[0] = 100; // 直接修改了 student 对象的内部 homeworkScores 数组!为避免此类问题,应采用“防御性复制”(Defensive Copying)策略:
import java.util.Arrays; // 用于数组复制
public class Student {
private String name;
private int[] homeworkScores;
private int[] examScores;
public Student(String name) {
this.name = name;
this.homeworkScores = new int[6];
this.examScores = new int[3];
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// 防御性复制的Getter
public int[] getHomeworkScores() {
return homeworkScores.clone(); // 返回副本
}
// 防御性复制的Setter
public void setHomeworkScores(int[] homeworkScores) {
if (homeworkScores == null || homeworkScores.length != 6) {
throw new IllegalArgumentException("Homework scores array must contain exactly 6 elements.");
}
this.homeworkScores = homeworkScores.clone(); // 存储副本
}
// 防御性复制的Getter
public int[] getExamScores() {
return examScores.clone(); // 返回副本
}
// 防御性复制的Setter
public void setExamScores(int[] examScores) {
if (examScores == null || examScores.length != 3) {
throw new IllegalArgumentException("Exam scores array must contain exactly 3 elements.");
}
this.examScores = examScores.clone(); // 存储副本
}
// ... getHomeworkAverage() 和 getFinalScore() 方法不变
public double getHomeworkAverage() {
if (homeworkScores == null || homeworkScores.length == 0) {
return 0.0;
}
int sum = 0;
for (int score : homeworkScores) {
sum += score;
}
return (double) sum / homeworkScores.length;
}
public double getFinalScore() {
if (examScores == null || examScores.length < 3) {
return 0.0;
}
double exam1Weight = 0.15;
double exam2Weight = 0.25;
double exam3Weight = 0.30;
double homeworkWeight = 0.30;
double finalScore = (examScores[0] * exam1Weight) +
(examScores[1] * exam2Weight) +
(examScores[2] * exam3Weight) +
(getHomeworkAverage() * homeworkWeight);
return finalScore;
}
}将UML类图转换为Java对象是一个设计与实现的过程,需要关注以下几点:
通过遵循这些原则,可以有效地将UML设计转化为高质量的Java代码,构建出结构清晰、功能完善且安全可靠的软件组件。
以上就是从UML类图到Java对象实现:构造器与数组处理实践的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号