学生管理系统项目【所有知识点整合】

1. 学生管理系统项目

尝试完成以下功能
实体类:
学生类:
id, 姓名,年龄,性别,成绩
需要使用数组保存学生信息
Student[] allStu
需要完成的方法
1. 根据学生的ID,找到对应的学生对象【完成】
2. 完成方法,添加新学生
3. 完成方法,删除指定ID的学生
4. 完成方法,展示数组中所有的学生信息
5. 根据学生成绩,完成降序排序
1.1 包结构划分
包名规范:
1. 所有的单词全部小写
2. 不同的单词直接使用 . 隔开
3. 包结构其实对应的就是一个真实的目录结构 包结构的使用是为了在开发中让代码结构更加明确,更好管理,会慢慢接触到MVC设计模式。
MVC ==> Model Viewer Controller 目前学生管理系统需要的包【目前功能所需】
实体类 : 所有的实体类都会在一个包下
管理类 : 需要一个管理类来管理学生操作【核心】,需要一个包
主方法类 : 主方法
测试类: 测试功能,养成习惯,对于代码中的功能,写一个测试一个,今天会到用@Test 包名:
com.qfedu.student.system
--| entity 实体类包
--| manager 管理类包
--| mainproject 主方法所在包
--| testsystem 测试类
1.2 学生实体类
package com.qfedu.student.system.entity;

/**
* 学生实体类
*
* @author Anonymous
*
*/
public class Student {
private int id;
private String name;
private int age;
private char gender;
private int score; public Student() {} public Student(int id, String name, int age, char gender, int score) {
super();
this.id = id;
this.name = name;
this.age = age;
this.gender = gender;
this.score = score;
} public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public char getGender() {
return gender;
} public void setGender(char gender) {
this.gender = gender;
} public int getScore() {
return score;
} public void setScore(int score) {
this.score = score;
} /**
* 使用System.out.println打印展示Student类对象时
* 是直接自动调用toString方法,展示该方法返回String字符串内容
*/
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", age=" + age + ", gender=" + gender + ", score=" + score
+ "]";
}
}
1.3 管理类功能分析
管理类:
1. 数据的保存
2. 数据处理
CRUD 增删改查 数据的保存
明确使用的是一个Student类型的数据
Student[] allStus;
问题:
成员变量
使用一个成员变量数组来保存对应的数据,所有的内容都依赖于类对象的操作
来完成,而且每一个管理类对象中保存的数据都是不一样的。
目前的不一样,是为了更好的复用性,后来的数据一样,是为了数据的统一性
静态成员变量
不关有多少个类对象,当前数据有且只有一份!!!
复用问题!!! 当前管理类
功能后期是考虑复用的!!!
不管是数据的存储方式,数据的处理方式,都要需要考虑满足多种情况,多种方式。
1.4 管理类构造方法
	因为当前管理类内的成员变量是一个数组,当前构造方法需要对于保存学生信息的数组进行初始化操作。
1. 传入参数是一个学生数组 【不行】
2. 传入参数是一个数组容量 √ 传入一个数组,操作性,包括安全性都是存在一定的隐患。操作性较差,用户需要提供真实管理数据的空间,繁琐,引用指向有可能导致数据丢失。
传入一个数组容量,用户操作自由度更高!!!方便!!!快捷!!!省心省事!!! 要求传入的参数是一个数组容量,有没有要求???
1. int
2. 非负
3. int类型的最大值
【补充】Java中数组容量范围是在int范围以内,要求数组容量不得超出int范围
Integer.MAX_VALUE - 8 为什么-8后面解释!!! 构造方法这里提供两种
1. 无参数构造方法
用户不用指定容量,我们给予用户一个初始化容量使用
2. 有参数构造方法
用户指定底层数组容量,要求数据在合理范围以内
1.5 构造方法完成和成员变量补充
package com.qfedu.student.system.manager;

import com.qfedu.student.system.entity.Student;

public class StudentManager {
/**
* 私有化保存学生信息的数组,对外不能公开,有且只针对于当前管理类使用
* 初始化为null
*/
private Student[] allStus = null; /**
* DEFAULT_CAPACITY 默认容量,这里是一个带有名字的常量
*/
private static final int DEFAULT_CAPACITY = 10; /**
* 数组最大容量,是int类型最大值 - 8
* -8等我给你讲
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; /**
* 无参数构造方法,但是需要创建底层保存学生数据的Student数组,因为当前数组
* 不存在,指向为null
*
*/
public StudentManager() {
allStus = new Student[DEFAULT_CAPACITY];
} /**
* 用户指定初始化容量,但是要求初始化容量在合理范围以内,不能小于0 ,不能
* 大于数组的最大值,MAX_ARRAY_SIZE
*
* @param initCapacity 用户指定的初始化容量
*/
public StudentManager(int initCapacity) {
if (initCapacity < 0 || initCapacity > MAX_ARRAY_SIZE) {
System.out.println("Input Parameter is Invalid!");
/* 异常抛出!!! 补充该知识点 暂时留下一个 System.exit(0) 退出程序 */
System.exit(0);
} allStus = new Student[initCapacity];
}
}
1.6 增删改查方法实现
1.6.1 增【重点】
分析:
权限修饰符:
public √
private 如果私有化,类外无法使用,不能操作数据
是否需要static修饰:
不需要的!!!
保存学生信息的数组是static修饰还是非static修饰???
非static修饰
如果当前方法使用static修饰,是没有办法操作类内的成员变量的!!!
返回值类型:
boolean
添加成功返回true,添加失败返回false
方法名:
add
添加
形式参数列表:
Student student
方法声明:
public boolean add(Student stu) 这里需要采用尾插法数据存入,这里需要一个计数器
int类型变量
局部变量:
方法运行结束GG思密达,没有了,不存在了,无法保存数据
成员变量:
可以保证每一个StudentManager对象中存储的内容都是独立,是根据当前数组中
存储数据的容量来确定
静态成员变量:
静态成员变量和类对象无关,而且独此一份,每一个StudentManager对象中保存
的数据个数都是独立,是不合理的!!!
/**
* 当前方法是添加学生类对象到StudentManager中,保存到底层的Student类型数组
*
* @param stu Student类对象
* @return 添加成功返回true,失败返回false
*/
public boolean add(Student stu) {
allStus[size] = stu;
size += 1; return true;
}
目前存在的问题:
1. 好像没有错误情况处理???
2. 容量不够用怎么办??? 好像没有错误情况处理???
需要异常处理来辅助完成错误或者说异常处理。 容量不够用怎么办???
扩容!!!
数组的容量在创建之后是无法修改的!!!
重新创建一个数组!!!新数组要求比原本的数组容量大。
从原数据数组迁移数据到新数组中
重新赋值成员变量allStus保存的空间地址指向新数组
1.6.2 grow方法,底层数组容量扩容方法【核心】
流程
1. 获取原数组容量
2. 计算得到新数组容量
3. 创建新数组
4. 迁移数据
5. 保存新数组地址 方法分析:
权限修饰符:
public 类外可以随便调用,数组容量不受控制,我们期望的是在数组添加元素时
容量不足的情况下,才会调用当前grow方法,public不合适! 【不合适】
private 核心操作,主要是在类内使用,类外不能调用当前方法。√
是否需要static修饰:
因为需要操作类内的底层数组,数组非static修饰,不需要使用static
返回值类型:
void 当前方法不需要返回值
方法名:
grow
形式参数列表:
要求最小容量
为了保证add操作在合理的容量范围以内(MAX_ARRAY_SIZE)操作成功,这里要求
通过add方法告知grow方法,最小要求容量扩容到多少?
需要考虑一些极端情况:
1. 添加多个,超出了grow增加的范围
2. 原数组容量为1,扩容之后不够用
方法声明:
private void grow(int minCapacity);
/**
* 类内私有化方法,用于在添加元素过程中,出现当前底层数组容量不足的情况下
* 对底层数组进行扩容操作,满足使用要求
*
* @param minCapacity 添加操作要求的最小容量
*/
private void grow(int minCapacity) {
// 1. 获取原数组容量
int oldCapacity = allStus.length; // 2. 计算得到新数组容量,新数组容量大约是原数组容量的1.5倍
int newCapacity = oldCapacity + oldCapacity / 2; // 3. 判断新数组容量是否满足最小容量要求
if (minCapacity > newCapacity) {
newCapacity = minCapacity;
} // 4. 判断当前容量是否超出了MAX_ARRAY_SIZE
if (newCapacity > MAX_ARRAY_SIZE) {
/* 这里需要一个异常处理,目前我们采用程序退出 */
System.exit(0);
} // 5. 创建新数组
Student[] temp = new Student[newCapacity]; // 6. 数据拷贝
for (int i = 0; i < oldCapacity; i++) {
temp[i] = allStus[i];
} // 7. 使用allStus保存新数组首地址
allStus = temp;
}
1.6.3 删【重点】
方法分析:
权限修饰符:
public √
private 【不合适】
是否需要static修饰:
不需要
返回值类型:
boolean 删除成功返回true,删除失败返回false
方法名:
remove 移除
形式参数列表:
int id
方法声明:
public boolean remove(int id) 流程:
1. 根据ID找出对应的学生对象在数组中的下标位置
2. 根据下标位置删除元素,从删除位置开始,之后的元素整体先前移动
3. 最后一个原本存在数据的位置赋值为null
4. size 有效元素个数 -= 1
/**
* 根据用户指定的ID号,删除对应学生类对象
*
* @param id 指定的学生ID好
* @return 删除成功返回true,删除失败返回false
*/
public boolean remove(int id) {
int index = -1; // 遍历数组的终止条件为size,有效元素个数
for (int i = 0; i < size; i++) {
if (id == allStus[i].getId()) {
index = i;
break;
}
} /*
* 以上代码循环结束,如果index的值为-1,证明没有找到对应的元素
* 当前方法无法进行删除操作,返回false
*/
if (-1 == index) {
System.out.println("Not Found!");
return false;
} /*
* 如果index值不是-1,表示找到了对应需要删除的元素,进行删除操作
*
* 假设原数组容量10,有效元素个数为10,删除下标为5的元素
* 数组[5] = 数组[6];
* 数组[6] = 数组[7];
* 数组[7] = 数组[8];
* 数组[8] = 数组[9];
* 数组[9] = null;
*
* 数组[i] = 数组[i + 1];
*/
for (int i = index; i < size - 1; i++) {
allStus[i] = allStus[i + 1];
} // 原本最后一个有效元素位置赋值为null
allStus[size - 1] = null; // 有效元素个数 - 1
size -= 1; return true;
}
1.6.4 查 根据学生的ID,找到对应的学生对象【重点】
方法分析:
权限修饰符
public √
private
是否需要static修饰
不需要
返回值类型:
Student学生类对象
方法名:
get 获取
形式参数列表:
int id
方法声明:
public Student get(int id)
/**
* 根据指定的ID获取对应的Student类对象
*
* @param id 指定的ID号
* @return 返回对应的Student类对象, 如果没有找到,返回null
*/
public Student get(int id) {
int index = findIndexById(id); return index > -1 ? allStus[index] : null;
}
1.6.5 补充方法,根据ID获取对应下标位置
方法分析:
权限修饰符:
public
private √ 给内部其他方法使用的一个功能,不需要对外
是否需要static修饰
不需要
返回值类型:
int 需要的是一个下标,为int类型
方法名:
findIndexById
形式参数列表:
int id
方法声明:
private int findIndexById(int id)
/**
* 类内私有化方法,用于根据指定ID获取对应的下标位置,提供给其他方法使用
*
* @param id 指定ID号
* @return 返回值是对应的下标位置,返回值大于等于0 表示找到对应元素,返回-1没有找到
*/
private int findIndexById(int id) {
int index = -1; for (int i = 0; i < size; i++) {
if (id == allStus[i].getId()) {
index = i;
break;
}
} return index;
}

面向对象案例 - 学生信息管理系统V1.0的更多相关文章

  1. 面向对象案例-学生信息管理系统V1.1

    1.学生类 package com.qfedu.student.entity; /** * 学生类实体 * * @author GGGXXC * */ public class Student { p ...

  2. 面向对象案例-学生信息管理系统V0.6

    更新版本 面向对象案例 - 学生信息管理系统V1.0 项目要求: 实体类: 学生类: id, 姓名,年龄,性别,成绩 需要使用数组保存学生信息 Student[] allStu 需要完成的方法 1. ...

  3. 学生信息管理系统v1.0

    昨天一个教师朋友找到我,告诉我现在学期末他工作比较忙.需要统计处理很多学生信息,想让我帮他做一个管理系统.实现的功能就是把WPS表格转化成Word文档,将每一个学生的信息都能够分开,并且要根据名字找到 ...

  4. PHP案例:学生信息管理系统

    -- Database: test -- 表的结构 message CREATE TABLE `message` ( `id` tinyint(1) NOT NULL PRIMARY KEY AUTO ...

  5. python 04 学生信息管理系统

    今天任务不多,做了学生信息管理系统1.0,使用字典存储学生个体信息,列表存储学生字典.注意dict定义要在循环体内,若定义成全局变量或循环体外,则旧数据会被新数据覆盖.dict属于可变类型数据,内容改 ...

  6. Android(java)学习笔记195:学生信息管理系统案例(SQLite + ListView)

    1.首先说明一个知识点,通常我们显示布局文件xml都是如下: setContentView(R.layout.activity_main): 其实每一个xml布局文件就好像一个气球,我们可以使用Vie ...

  7. 【Python3.6+Django2.0+Xadmin2.0系列教程之二】学生信息管理系统(入门篇)

    上一篇我们已经创建好了一个Xadmin的基础项目,现在我们将在此基础上构建一个同样很基础的学生信息管理系统. 一.创建模型 模型是表示我们的数据库表或集合类,并且其中所述类的每个属性是表或集合的字段, ...

  8. Android(java)学习笔记188:学生信息管理系统案例(SQLite + ListView)

    1.首先说明一个知识点,通常我们显示布局文件xml都是如下: setContentView(R.layout.activity_main): 其实每一个xml布局文件就好像一个气球,我们可以使用Vie ...

  9. <每日一题>题目7:简单的学生管理系统V1.0

    ''' # 学生管理系统v1.0 # 添加学生的信息 # 删除学生的信息 # 修改学生的信息 # 查看学生的信息 #遍历学生的信息 #退出系统 ''' import json #1 显示操作功能 de ...

随机推荐

  1. 【K8S】基于单Master节点安装K8S集群

    写在前面 最近在研究K8S,今天就输出部分研究成果吧,后续也会持续更新. 集群规划 IP 主机名 节点 操作系统版本 192.168.175.101 binghe101 Master CentOS 8 ...

  2. 图论--最短路--SPFA

    SPFA算法(shortest path faster algorithm)算法是西南交通大学段凡丁于1994年发表的,它在Bellman-ford算法的基础上进行了改进,使其在能够处理待负权图的单元 ...

  3. 【Java8新特性】一张图带你领略Java8有哪些新特性

    写在前面 很多小伙伴留言说,冰河你能不能写一些关于Java8的文章呢,看书看不下去,看视频进度太慢.好吧,看到不少读者对Java8还是比较陌生的,那我就写一些关于Java8的文章吧,希望对大家有所帮助 ...

  4. 题目分享F 二代目

    题意:T个点R种双向边,P种单向边,求点S到每个点的最短距离 分析:(这再看不出来是spfa就该**了) 首先,这题能否用spfa就看他是否有负环呗,显然,双向边的权值非负,单向边还有个啥政策,总之显 ...

  5. 开源 一套 Blazor Server 端精致套件

    Blazor 作为一种 Web 开发的新技术已经发展有一段时间了,有些人标称 无 JS 无 TS,我觉得有点误导新人的意味,也有人文章大肆宣传 Blazor 是 JavaScript 的终结者,是为了 ...

  6. HTTP请求头中的X-Forwarded-For介绍

    概述 我们在做nginx方向代理的时候,为了记录整个代理过程,我们往往会在配置文件中加上如下配置: location ^~ /app/download/ { ... proxy_set_header ...

  7. B - Planning 早训 贪心

    B - Planning 这个题目我知道要贪心,也知道怎么贪,但是写不出来,感觉自己好菜. 这个题目要用优先队列维护. 题目大意是飞机延误,不同的飞机每次延误一分钟,它的代价不同,然后问,怎么安排才能 ...

  8. 线段树 C - Connected Components? CodeForces - 920E

    这个题目居然可以用线段树写,好震惊,如果不是在线段树专题肯定想不到,但是就算在线段树的专题里面,我也不太会怎么写. 这个题目大意是,给你n m n代表n个点,m代表m条边,然后就是m行,每行两个数字, ...

  9. Collections集合工具类常用的方法

    java.utils.Collections //是集合工具类,用来对集合进行操作.部分方法如下: public static <T> boolean addAll(Collection& ...

  10. u-boot spl 学习总结

    什么是SPL? SPL(secondary program loader)是一个十分小的bin文件,它是用来引导主u-boot文件.对于一些SRAM很小的SOC,无法一次性加载ROM中的bootloa ...