多类合作

以eclipse各个包来合作完成该系统,且后期会不断完善优化该项目

包名规范:
1. 所有的单词全部小写
2. 不同的单词直接使用 . 隔开
3. 包结构其实对应的就是一个真实的目录结构

包结构的使用是为了在开发中让代码结构更加明确,更好管理,会慢慢接触到MVC设计模式。
MVC ==> Model Viewer Controller

目前学生管理系统需要的包【目前功能所需】
实体类 : 所有的实体类都会在一个包下
管理类 : 需要一个管理类来管理学生操作【核心】,需要一个包
主方法类 : 主方法
测试类: 测试功能,养成习惯,对于代码中的功能,写一个测试一个,今天会到用@Test

包名:
com.qfedu.student.system
–| entity 实体类包
–| manager 管理类包
–| mainproject 主方法所在包
–| testsystem 测试类

package com.mhj.student.entity;

public class Student {
	/**
	 * 学生管理系统
	 *  实现类:
	 *  iD
	 *  名字
	 *  年龄
	 *  性别
	 *  成绩
	 */
	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;
	}

	// get(查询)和set(修改)方法
	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
				+ "]"; 
	}
	
	// 展示对象属性
	public void mprint() {
		System.out.println(iD + name +  age + gender + score);
	}
}

管理类:

  1. 数据的保存
  2. 数据处理
    CRUD 增删改查
    数据的保存
    明确使用的是一个Student类型的数据 Student[] allStus;
    问题:
    成员变量
    `使用一个成员变量数组来保存对应的数据,所有的内容都依赖于类对象的操作
    来完成,而且每一个管理类对象中保存的数据都是不一样的。
    目前的不一样,是为了更好的复用性,后来的数据一样,是为了数据的统一性
    静态成员变量
    不关有多少个类对象,当前数据有且只有一份!!!
    复用问题!!!当前管理类 功能后期是考虑复用的!!!
    不管是数据的存储方式,数据的处理方式,都要需要考虑满足多种情况,多种方式。

增删改查:【增】【删】【查】明天更新【改】

分析:
权限修饰符:
public √
private 如果私有化,类外无法使用,不能操作数据
是否需要static修饰:
不需要的!!!
保存学生信息的数组是static修饰还是非static修饰???
非static修饰
如果当前方法使用static修饰,是没有办法操作类内的成员变量的!!!
返回值类型:
boolean
添加成功返回true,添加失败返回false
方法名:
add
添加
形式参数列表:
Student student
方法声明:
public boolean add(Student stu)

这里需要采用尾插法数据存入,这里需要一个计数器
int类型变量
局部变量:
方法运行结束GG思密达,没有了,不存在了,无法保存数据
成员变量:
可以保证每一个StudentManager对象中存储的内容都是独立,是根据当前数组中
存储数据的容量来确定
静态成员变量:
静态成员变量和类对象无关,而且独此一份,每一个StudentManager对象中保存
的数据个数都是独立,是不合理的!!!

package com.mhj.student.manager;

// 导入Student类的包
import com.mhj.student.entity.Student;

public class StudentManager {
	/**
	 * 新建对象数组 初始化为null
	 * 
	 * 推荐使用private修饰 类内操作该数组
	 */
	private Student[] allStus = null;
	
	/**
	 * 定义一个类内使用的静态常量,名字叫做DEFAULT_CAPACITY
	 * 用来初始化数组容量
	 */
	private static final int DEFAULT_CAPACITY = 10;
	
	/*
	 * int数组容量的最大值,
	 */
	private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
	
	// 无参构造方法
	public StudentManager() {
		// 用户如不初始化数组容量,则在创建对象时先给予数组一个容量
		allStus = new Student[DEFAULT_CAPACITY];
	}
	
	/**
	 * 用户指定初始化对象数组的容量,但数组的容量不能小于0且不能大于MAX_ARRAY_SIZE
	 * @param newCapacity 这是用户需要的数组容量个数
	 */
	// 公开的构造方法 ,参数是用户需要的数组容量
	public StudentManager(int newCapacity) {
		// 判断用户输入的是否合法
		if(newCapacity < 0 || newCapacity > MAX_ARRAY_SIZE) {
			System.out.println("越界!!!");
			System.exit(0);
		}
		// 如果容量没有越界则将容量扩展至用户需要的容量
		allStus = new Student[newCapacity];
	}
	
	private int size = 0;
	//添加加学生对象的方法
	/**
	 * 添加学生对象的方法size为保存对象的下标位置
	 * 
	 * @param stu 添加保存的对象
	 * @return 添加成功返回true
	 */
	public boolean add(Student stu) {
		
		if(size == allStus.length) {
			System.out.println("扩容");
			grow(size + 1);
		}
		
		allStus[size] = stu;
		size += 1;
		
		return true;
	}
	
	/*
	 * 但是目前有一个问题, 如果用户不指定容量,初始容量对象只能储
	 * 10个,这里需要一个扩容的方法,
	 */
	private void grow(int minCapacity) {
		// 获取旧数组的容量
		int oldCapacity = allStus.length;
		
		// 创建新数组,扩容百分之五十左右
		int newCapacity = oldCapacity + oldCapacity / 2;
		
		// 判断新数组容量是否满足最小容量需求
		if(newCapacity < minCapacity) {
			newCapacity = minCapacity;
		}
		
		// 判断当前数组容量是否超出了MAX_ARRAY_SIZE
		if(newCapacity > MAX_ARRAY_SIZE) {
			// 如果超出范围则退出程序,目前而言,后期可用try抛出异常
			System.exit(0);
		}
		
		Student[] temp = new Student[newCapacity];
		
		// 拷贝新数组
		for (int i = 0; i < oldCapacity; i++) {
			temp[i] = allStus[i];
		}
		
		allStus = temp;
	}
	
	// 根据对应的ID号删除指定学生
	public boolean remove(int iD) {
		// 设定一个负数假设没有对应的id
		int index = -1;
		
		// 遍历所有对象 如果找到对应id的对象,以index保存下标位置
		for (int i = 0; i < size; i++) {
			if (iD == allStus[i].getiD()) {
				index = i;
				break;
			}
		}
		 
		// 判断如果没找到则返回false
		if (index < 0) {
			System.out.println("未找到");
			return false;
		}
		
		// 删除操作:将要删除学生的对象被后面的覆盖,起始位置是index,以此类推,
		/*
		 * 
		 */
		for (int i = index; i < size; i++) {
			allStus[i] = allStus[i + 1];
		}
		
		// 原来最后一个对象赋值为null
		allStus[size - 1] = null;
		
		size -= 1;
		
		return true;
	}
	
	// 打印输出对象保存属性方法
	public void print() {
		for (int i = 0; i < size; i++) {
			allStus[i].mprint();
		}
	}
	
	/**
	 * 该方法与下面的方法合用,该方法通过findIndexById方法返回的下标位置找到对应的对象
	 * 且为了复用性将一个方法拆分成两个方法,findIndexById方法可寻找下标位置
	 * 
	 * @param id 需要寻找对象的id
	 * @return 返回需要寻找的对象
	 */
	public Student get(int id) {
		int index = findIndexById(id);
		
		if (index < 0) {
			System.out.println("未找到");
			return null;
		}
		allStus[index].mprint();
		return allStus[index];
	}
	
	/**
	 * 该方法是寻找对应id的下标位置
	 * @param id 需要寻找的id
	 * @return 返回寻找到的下标位置
	 */
	private int findIndexById(int id) {
		// 初始化一个变量,假设要寻找的id不存在
		int index = -1;
		
		// 以for循环遍历整个数组,寻找对应id的对象下标位置
		for (int i = 0; i < size; i++) {
			if (id == allStus[i].getiD()) {
				index = i;
				break;
			}
		}
		return index;
	}
}