Day12
一、内部类
知识点:内部类
理解:一个类的内部声明另外一个类
分类:
成员内部类
静态内部类
接口内部类
局部内部类
匿名内部类
1.成员内部类
知识点:成员内部类
需求:创建成员内部类的对象,并调用方法
小结:
1.创建成员内部类对象,必须先创建外部类对象,再创建内部类对象
2.成员内部类可以使用外部类所有的属性//外部类 public class Outter { private String str1 = "属性1"; String str2 = "属性2"; protected String str3 = "属性3"; public String str4 = "属性4"; final String str5 = "属性5"; static String str6 = "属性6"; static final String str7 = "属性7"; //成员内部类 class Inner{ String str1 = "成员内部类的属性"; public void method(){ System.out.println("成员内部类的方法"); System.out.println(str1);//this.str1 System.out.println(Outter.this.str1);//调用外部的属性 System.out.println(str2);//Outter.this.str2 System.out.println(str3);//Outter.this.str3 System.out.println(str4);//Outter.this.str4 System.out.println(str5);//Outter.this.str5 System.out.println(str6);//Outter.str6 System.out.println(str7);//Outter.str7 } }
public static void main(String[] args) { Inner inner = new Outter().new Inner(); inner.method(); }
2.静态内部类
知识点:静态内部类
需求:创建静态内部类的对象,并调用方法
小结:
1.创建静态内部类对象,不用创建外部类对象
2.静态内部类只能使用外部类的静态属性//外部类 public class Outter { static String str1 = "属性1"; static final String str2 = "属性2"; //静态内部类 static class Inner{ public void method(){ System.out.println("静态内部类的方法"); System.out.println(str1);//Outter.str6 System.out.println(str2);//Outter.str7 } }
public static void main(String[] args) { Inner inner = new Outter.Inner(); inner.method(); }
3.接口内部类
知识点:接口内部类
需求:创建接口内部类的对象,并调用方法
小结:
1.接口内部类就是静态内部类
2.接口内部类默认使用public static修饰//外部接口 public interface Outter { //接口内部类 //public static class Inner{ class Inner{ public void method(){ System.out.println("接口内部类的方法"); } } }
public class Test01 { public static void main(String[] args) { Inner inner = new Outter.Inner(); inner.method(); }
4.局部内部类
知识点:局部内部类
需求:调用局部内部类里的方法
小结:
局部内部类不能使用访问修饰符修饰(因为局部内部类的作用域就是在该方法内)//外部类 public class Outter { public void method(){ //局部内部类 class Inner{ public void innerMethod(){ System.out.println("局部内部类里的方法"); } } //创建局部内部类对象 Inner inner = new Inner(); inner.innerMethod(); } }
public static void main(String[] args) { Outter outter = new Outter(); outter.method(); }
注意:局部内部类使用到外部类方法里的变量,该变量在JDK1.8开始会自动变成常量
做实验:
//外部类 public class Outter { public Object method(){ int i = 100; //局部内部类 class Inner{ @Override public String toString() { return "局部内部类里的方法:" + i; } } //创建局部内部类对象 Object obj = new Inner(); return obj; } }
public static void main(String[] args) { Outter outter = new Outter(); Object obj = outter.method(); //这里打印obj.toString和直接打印obj是一样的,因为println方法会隐性地调用toString方法 System.out.println(obj.toString()); }
5.匿名内部类
public abstract class A { public abstract void method(); } public class Test01 { //知识点:匿名内部类 public static void main(String[] args) { //1.底层创建匿名类(Test01$1.class),继承A类,重写method() //2.创建匿名类对象 //3.将匿名类对象的内存地址赋值给父类的引用 -- 多态 A a = new A() { @Override public void method() { // TODO Auto-generated method stub } }; a.method(); } }
public interface I1 { public void method(); } public class Test01 { /** * 知识点:匿名内部类 */ public static void main(String[] args) { //1.底层创建匿名类(Test01$1.class),实现I1接口中的method() //2.创建匿名类的对象 //3.将匿名类对象的内存地址赋值给接口的引用 -- 多态 I1 i1 = new I1() { @Override public void method() { } }; i1.method(); } }
小结
A类的对象只在B类中使用,并且A类使用到B类所有的属性 – 可以将A类设置为B类的成员内部类(常用)
A类的对象只在B类中使用,并且A类使用到B类的静态属性 – 可以将A类设置为B类的静态内部类(常用)
A类(抽象类)的子类只创建一次对象,就没必要去创建子类 – 直接使用匿名内部类(new A())(常用)
I1接口的实现类只创建一次对象,就没必要去创建实现类 – 直接使用匿名内部类(new I1())(常用)A类的对象只在B类某个方法中使用 – 可以将A类设置为B类的局部内部类(少见)
A类的对象只在I1接口中使用 – 可以将A类设置为I1接口的接口内部类(少见)
二、学生管理系统(添加、删除、查询)
package com.qf.sms;
import com.qf.pojo.Student;
public interface SMS {
int NAME = 1;
int SEX = 2;
int AGE = 3;
int CLASS_ID = 4;
int ID = 5;
/**
* 添加学生
* @param stu 目标学生
* @return 状态码
*/
public int add(Student stu);
/**
* 扩容
*/
public void expansion();
/**
* 删除学生
* @param classId 班级号
* @param id 学号
* @return 状态码
*/
public int remove(String classId,String id);
/**
* 修改学生
* @param classId 班级号
* @param id 学号
* @param type 修改类型(1-姓名 2-性别 3-年龄 4-班级号 5-学号)
* @param val 需要修改的值
* @return 状态码
*/
public int update(String classId,String id,int type,Object val);
/**
* 根据姓名查询学生数组
* @param name 姓名
* @return 学生数组
*/
public Student[] getStudentsByName(String name);
/**
* 根据性别查询学生数组
* @param sex 性别
* @return 学生数组
*/
public Student[] getStudentsBySex(char sex);
/**
* 根据年龄段查询学生数组
* @param start 开始年龄-包含
* @param end 结束年龄 - 排他
* @return 学生数组
*/
public Student[] getStudentsByAges(int start,int end);
/**
* 根据班级号查询学生数组
* @param classId 班级号
* @return 学生数组
*/
public Student[] getStudentsByClassId(String classId);
/**
* 查询学生在容器中的下标
* @param stu 目标学生
* @return 如果学生在容器中返回下标,否则返回-1
*/
public int getStuIndex(Student stu);
/**
* 打印学生管理系统里所有的学生
*/
public void println();
/**
* 打印指定的学生数组
* @param stus
*/
default void println(Student[] stus){
for (Student stu : stus) {
System.out.println(stu);
}
}
}
package com.qf.sms.impl;
import java.util.Arrays;
import com.qf.pojo.Student;
import com.qf.sms.SMS;
import com.qf.utils.StuInfoUtil;
public class SMSImpl implements SMS{
//学生容器
private Student[] stus;
//容器数据量
private int size;
//默认容量
private static final int INIT_CAPACITY = 3;
public SMSImpl() {
stus = new Student[INIT_CAPACITY];//[null,null,null]
//假数据
add(new Student("小希", '女', 21, "2402", "001"));
add(new Student("唐亮", '男', 21, "2402", "004"));
add(new Student("彭从升", '男', 21, "2402", "005"));
add(new Student("侯小康", '男', 21, "2402", "006"));
add(new Student("唐亮", '男', 24, "2403", "001"));
}
public SMSImpl(int capacity) {
stus = new Student[capacity];
}
@Override
public int add(Student stu) {
//1.判断学生信息合法性
if(!StuInfoUtil.isStu(stu)){
return -1;
}
//2.判断是否有重复学生
if(getStuIndex(stu) != -1){
return -2;
}
//3.判断是否扩容
if(size == stus.length){
expansion();
}
//4.添加学生
stus[size++] = stu;
return 1;
}
@Override
public void expansion() {
int oldCapacity = stus.length;
int newCapacity = oldCapacity + (oldCapacity>>1);//扩容机制:1.5倍
stus = Arrays.copyOf(stus, newCapacity);
}
@Override
public int remove(String classId, String id) {
//1.判断学生信息合法性
if(!StuInfoUtil.isClassId(classId) || !StuInfoUtil.isId(id)){
return -1;
}
//2.判断是否有该学生
Student stu = new Student(classId, id);//临时学生对象
int index = getStuIndex(stu);
if(index == -1){
return -2;
}
//3.删除学生
for (int i = index; i < size-1; i++) {
stus[i] = stus[i+1];
}
size--;
return 1;
}
@Override
public int update(String classId, String id, int type, Object val) {
// TODO Auto-generated method stub
return 0;
}
@Override
public int getStuIndex(Student stu) {
for (int i = 0; i < size; i++) {
if(stus[i].equals(stu)){
return i;
}
}
return -1;
}
@Override
public Student[] getStudentsByName(String name) {
//1.判断学生信息合法性
if(!StuInfoUtil.isName(name)){
return null;
}
//2.确定符合条件的学生个数
int count = 0;
for (int i = 0; i < size; i++) {
if(stus[i].getName().equals(name)){
count++;
}
}
if(count == 0){
return null;
}
//3.创建新数组
Student[] newStus = new Student[count];
//4.将符合条件的学生对象赋值到新数组中
int index = 0;
for (int i = 0; i < size; i++) {
if(stus[i].getName().equals(name)){
newStus[index++] = stus[i];
}
}
return newStus;
}
@Override
public Student[] getStudentsBySex(char sex) {
//1.判断学生信息合法性
if(!StuInfoUtil.isSex(sex)){
return null;
}
//2.确定符合条件的学生个数
int count = 0;
for (int i = 0; i < size; i++) {
if(stus[i].getSex() == sex){
count++;
}
}
if(count == 0){
return null;
}
//3.创建新数组
Student[] newStus = new Student[count];
//4.将符合条件的学生对象赋值到新数组中
int index = 0;
for (int i = 0; i < size; i++) {
if(stus[i].getSex() == sex){
newStus[index++] = stus[i];
}
}
return newStus;
}
@Override
public Student[] getStudentsByAges(int start, int end) {
//1.判断学生信息合法性
if(!StuInfoUtil.isAge(start) || !StuInfoUtil.isAge(end)){
return null;
}
//2.确定符合条件的学生个数
int count = 0;
for (int i = 0; i < size; i++) {
int age = stus[i].getAge();
if(age>=start && age<end){
count++;
}
}
if(count == 0){
return null;
}
//3.创建新数组
Student[] newStus = new Student[count];
//4.将符合条件的学生对象赋值到新数组中
int index = 0;
for (int i = 0; i < size; i++) {
int age = stus[i].getAge();
if(age>=start && age<end){
newStus[index++] = stus[i];
}
}
return newStus;
}
@Override
public Student[] getStudentsByClassId(String classId) {
//1.判断学生信息合法性
if(!StuInfoUtil.isClassId(classId)){
return null;
}
//2.确定符合条件的学生个数
int count = 0;
for (int i = 0; i < size; i++) {
if(stus[i].getClassId().equals(classId)){
count++;
}
}
if(count == 0){
return null;
}
//3.创建新数组
Student[] newStus = new Student[count];
//4.将符合条件的学生对象赋值到新数组中
int index = 0;
for (int i = 0; i < size; i++) {
if(stus[i].getClassId().equals(classId)){
newStus[index++] = stus[i];
}
}
return newStus;
}
@Override
public void println() {
for (int i = 0; i < size; i++) {
System.out.println(stus[i]);
}
}
}
package com.qf.pojo;
public class Student {
private String name;
private char sex;
private int age;
private String classId;
private String id;
public Student() {
}
public Student(String classId, String id) {
this.classId = classId;
this.id = id;
}
public Student(String name, char sex, int age, String classId, String id) {
this.name = name;
this.sex = sex;
this.age = age;
this.classId = classId;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getClassId() {
return classId;
}
public void setClassId(String classId) {
this.classId = classId;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public boolean equals(Object obj) {
if(this == obj){
return true;
}
if(obj instanceof Student){
Student stu = (Student) obj;
if(classId.equals(stu.classId) && id.equals(stu.id)){
return true;
}
}
return false;
}
@Override
public String toString() {
return name + "\t" + sex + "\t" + age + "\t" + classId + "\t" + id;
}
}
package com.qf.utils;
import com.qf.pojo.Student;
//学生信息的工具类
public class StuInfoUtil {
public static boolean isStu(Student stu){
String name = stu.getName();
char sex = stu.getSex();
int age = stu.getAge();
String classId = stu.getClassId();
String id = stu.getId();
if(!isName(name) || !isSex(sex) || !isAge(age) || !isClassId(classId) || !isId(id)){
return false;
}
return true;
}
public static boolean isName(String name){
int len = name.length();
if(len<2 || len>16){
return false;
}
return true;
}
public static boolean isSex(char sex){
if(sex != '男' && sex != '女'){
return false;
}
return true;
}
public static boolean isAge(int age){
if(age<16 || age>40){
return false;
}
return true;
}
public static boolean isClassId(String classId){
int len = classId.length();
if(len != 4){
return false;
}
return true;
}
public static boolean isId(String id){
int len = id.length();
if(len != 3){
return false;
}
return true;
}
}
package com.qf.main;
import java.util.Scanner;
import com.qf.pojo.Student;
import com.qf.sms.SMS;
import com.qf.sms.impl.SMSImpl;
public class Main {
/**
* 知识点:学生管理系统
*/
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
SMS sms = new SMSImpl();
System.out.println("欢迎进入**学生管理系统");
boolean flag = true;
while(flag){
System.out.println("请选择以下功能:");
System.out.println("1 - 添加学生");
System.out.println("2 - 删除学生");
System.out.println("3 - 修改学生");
System.out.println("4 - 查询学生");
System.out.println("5 - 打印所有学生");
System.out.println("886 - 退出系统");
int num = scan.nextInt();
switch (num) {
case 1:
addMenu(scan, sms);
break;
case 2:
removeMenu(scan, sms);
break;
case 3:
break;
case 4:
System.out.println("请选择查询条件:");
System.out.println("1 - 根据姓名查询");
System.out.println("2 - 根据性别查询");
System.out.println("3 - 根据年龄段查询");
System.out.println("4 - 根据班级号查询");
int queryType = scan.nextInt();
switch (queryType) {
case 1:
System.out.println("请输入要查询的姓名:");
String name = scan.next();
stus = sms.getStudentsByName(name);
break;
case 2:
System.out.println("请输入要查询的性别:");
char sex = scan.next().toCharArray()[0];
stus = sms.getStudentsBySex(sex);
break;
case 3:
System.out.println("请输入要查询的开始年龄:");
int start = scan.nextInt();
System.out.println("请输入要查询的结束年龄:");
int end = scan.nextInt();
stus = sms.getStudentsByAges(start, end);
break;
case 4:
System.out.println("请输入要查询的班级号:");
String classId = scan.next();
stus = sms.getStudentsByClassId(classId);
break;
}
if(stus != null){
sms.println(stus);
}else{
System.out.println("没有查询到学生");
}
}
break;
case 5:
sms.println();
break;
case 886:
flag = false;
System.out.println("正在退出**学生管理系统,欢迎下次再来...");
break;
default:
System.out.println("输入错误,请重新输入");
break;
}
System.out.println("-------------------------");
}
//关闭资源
scan.close();
}
private static void removeMenu(Scanner scan, SMS sms) {
System.out.println("请输入班级号:");
String classId = scan.next();
System.out.println("请输入学号:");
String id = scan.next();
int removeCode = sms.remove(classId, id);
if(removeCode == -1){
System.out.println("删除失败 -- 学生信息不合法");
}else if(removeCode == -2){
System.out.println("删除失败 -- 没有该学生");
}else if(removeCode == 1){
System.out.println("删除成功");
}
}
private static void addMenu(Scanner scan, SMS sms) {
System.out.println("请输入姓名:");
String name = scan.next();
System.out.println("请输入性别:");
char sex = scan.next().toCharArray()[0];//"男" -> ['男'] -> '男'
System.out.println("请输入年龄:");
int age = scan.nextInt();
System.out.println("请输入班级号:");
String classId = scan.next();
System.out.println("请输入学号:");
String id = scan.next();
Student stu = new Student(name, sex, age, classId, id);
int addCode = sms.add(stu);
if(addCode == -1){
System.out.println("添加失败 -- 学生信息不合法");
}else if(addCode == -2){
System.out.println("添加失败 -- 有重复学生");
}else if(addCode == 1){
System.out.println("添加成功");
}
}
}