• 面向对象案例


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

    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;                                          
    }                                                          
    
  • 相关阅读:
    藕益大师示念佛法门
    【丁嘉丽老师】最新心得报告——生死无常,好好念佛(视频+文字)
    【视频+文字】刘素云老师:法雨惠群生--老实念佛不拐弯 今生一定到彼岸(附净空老法师点评)
    刘素云老师复讲《无量寿经》第16集
    《认识佛教》有声书-02-净空法师-初学佛课程(音)
    《认识佛教》有声书-01-净空法师-初学佛课程(音)
    【强烈推荐】科注学习班——自了法师分享:珍惜暇满人身宝(上)
    自了法师全集 | 无量寿经科注第四回学习班分享三十篇
    《2014净土大经科注》大汇总
    释自了法师:生死心不切,若真为生死之心不发,一切开示皆为戏论
  • 原文地址:https://www.cnblogs.com/raising/p/12853972.html
Copyright © 2020-2023  润新知