1、对象数组
数组的元素可以是基本数据类型,也可以是引用数据类型。当元素是引用类型中的类时,我们称为对象数组。
1.1 案例1
定义类Student,包含三个属性:学号number(int),年级state(int),成绩score(int)。 创建20个学生对象,学号为1到20,年级和成绩都由随机数确定。
问题一:打印出3年级(state值为3)的学生信息。
问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
提示:
1) 生成随机数:Math.random(),返回值类型double;
2) 四舍五入取整:Math.round(double d),返回值类型long。
/*
* 定义类Student,包含三个属性:学号number(int),年级state(int),成绩score(int)。
*/
public class Student {
int number;//学号
int state;//年级
int score;//成绩
public void info(){
System.out.println("number : " + number
+ ",state : " + state + ",score : " + score);
}
}
public class StudentTest {
public static void main(String[] args) {
// 对象数组
// String[] arr = new String[10];
// 数组的创建
Student[] students = new Student[20];
// 通过循环结构给数组的属性赋值
for (int i = 0; i < students.length; i++) {
// 数组元素的赋值
students[i] = new Student();
// 数组元素是一个对象,给对象的各个属性赋值
students[i].number = (i + 1);
students[i].state = (int) (Math.random() * 6 + 1);// [1,6]
students[i].score = (int) (Math.random() * 101);// [0,100]
}
// 问题一:打印出3年级(state值为3)的学生信息。
for (int i = 0; i < students.length; i++) {
if (students[i].state == 3) {
// System.out.println(
// "number:" + students[i].number + ",state:" + students[i].state + ",score:" + students[i].score);
students[i].info();
}
}
System.out.println("******************************");
// 问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
// 排序前
for (int i = 0; i < students.length; i++) {
// System.out.println(
// "number:" + students[i].number + ",state:" +
// students[i].state + ",score:" + students[i].score);
students[i].info();
}
System.out.println();
// 排序:
for (int i = 0; i < students.length - 1; i++) {
for (int j = 0; j < students.length - 1 - i; j++) {
if (students[j].score > students[j + 1].score) {
Student temp = students[j];
students[j] = students[j + 1];
students[j + 1] = temp;
}
}
}
// 排序后:
for (int i = 0; i < students.length; i++) {
// System.out.println(
// "number:" + students[i].number + ",state:" +
// students[i].state + ",score:" + students[i].score);
students[i].info();
}
}
}
内存解析:
注意点:
对象数组,首先要创建数组对象本身,即确定数组的长度,然后再创建每一个元素对象,如果不创建,数组的元素的默认值就是null,所以很容易出现空指针异常NullPointerException。
1.2 案例2--简易图书管理系统
package com.work.pojo;
/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-06 18:18
*@Description: TODO
*/
public class Book {
// 书籍编号
private String id;
// 书籍名称
private String name;
// 书籍作者
private String author;
// 书籍价格
private double price;
// 构造器
public Book() {
}
public Book(String id, String name, String author, double price) {
this.id = id;
this.name = name;
this.author = author;
this.price = price;
}
// setter和getter方法
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
// 重写toString方法
@Override
public String toString() {
return "Book{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
'}';
}
}
package com.work.service;
import com.work.pojo.Book;
/**
* @Author: 憨憨浩浩
* @CreateTime: 2023-12-06 18:19
* @Description: TODO
*/
public interface BookService {
// 添加书籍
public boolean addBook(Book book);
// 根据id删除书籍
public boolean deleteBookById(String id);
// 查询书籍
public void selectBooks();
// 根据id修改书籍名称
public boolean updateBookById(String id, String name);
}
package com.work.service.impl;
import com.work.pojo.Book;
import com.work.service.BookService;
/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-06 18:19
*@Description: TODO
*/
public class BookServiceImpl implements BookService {
// 定义数组对象
private Book[] books = new Book[10];
// 书籍数量--对应数组索引
private int index;
/**
* @description: 添加书籍
* @author: 三石
* @date: 2023/12/6 18:25
* @param: [book]
* @return: boolean
**/
@Override
public boolean addBook(Book book) {
boolean flag = true;
for (int i = 0; i < index; i++) {
if (book.getId().equals(books[i].getId())){
flag = false;
return flag;
}
}
if (index >= books.length) {
flag = false;
return flag;
}
books[index] = book;
index++;
return flag;
}
/**
* @description: 根据书籍id删除对应书籍
* @author: 三石
* @date: 2023/12/6 18:25
* @param: [id]
* @return: boolean
**/
@Override
public boolean deleteBookById(String id) {
for (int i = 0; i < index; i++) {
if (books[i].getId().equals(id)){
books[i] = books[index - 1];
books[index - 1] = null;
index--;
return true;
}else {
return false;
}
}
return false;
}
/**
* @description: 查询所有书籍
* @author: 三石
* @date: 2023/12/6 18:24
* @param: []
* @return: void
**/
@Override
public void selectBooks() {
for (int i = 0; i < books.length; i++) {
if (books[i] != null) {
System.out.println(books[i]);
}
}
}
/**
* @description: 根据书籍id修改书籍信息
* @author: 三石
* @date: 2023/12/6 18:58
* @param: [id, name]
* @return: boolean
**/
@Override
public boolean updateBookById(String id, String name) {
for (int i = 0; i < index; i++) {
if (books[i].getId().equals(id)){
books[i].setName(name);
return true;
}else {
return false;
}
}
return false;
}
}
package com.work.test;
import com.suyv.demo02.service.BookService;
import com.work.pojo.Book;
import com.work.service.impl.BookServiceImpl;
import java.util.Scanner;
/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-06 18:31
*@Description: TODO
*/
public class BookTest {
public static void main(String[] args) {
// 创建bookService对象,存储book对象
BookServiceImpl bookService = new BookServiceImpl();
Scanner scan = new Scanner(System.in);
System.out.println("============欢迎进入图书管理系统=====================");
while (true){
System.out.println("============请选择你的操作编号:1.添加图书 2.查询图书 "
+ "3.根据书籍编号删除书籍 4.根据书籍编号修改书籍信息 0.退出系统================");
// 接收输入的编号
int num = scan.nextInt();
switch (num){
case 1:
System.out.println("请输入图书编号:");
String id = scan.next();
System.out.println("请输入图书名称:");
String name = scan.next();
System.out.println("请输入图书作者:");
String author = scan.next();
System.out.println("请输入图书价格:");
double price = scan.nextDouble();
// 创建book对象
Book book = new Book(id,name,author,price);
// 添加图书
if (bookService.addBook(book)) {
System.out.println("添加成功");
}else {
System.out.println("添加失败");
}
break;
case 2:
// 查询图书
bookService.selectBooks();
break;
case 3:
System.out.println("请输入你要删除的书籍编号:");
id = scan.next();
// 删除图书
if (bookService.deleteBookById(id)) {
System.out.println("删除成功");
}else {
System.out.println("删除失败");
}
break;
case 4:
System.out.println("请输入你要修改的书籍编号:");
id = scan.next();
System.out.println("请输入修改后的书籍名称:");
name = scan.next();
// 修改图书
if (bookService.updateBookById(id, name)) {
System.out.println("修改成功");
}else {
System.out.println("修改失败");
}
break;
case 0:
System.out.println("================退出系统======================");
return;
default:
System.out.println("===========该功能暂未开放=============");
}
}
}
}
2、接口
2.1 接口基本概述及格式
2.1.1 接口概述
接口,是Java语言中一种引用类型,是方法的集合,如果说类的内部封装了成员变量、构造方法和成员方法,那么接口的内部主要就是封装了方法(功能),包含抽象方法 (JDK7及以前) , 默认方法和静态方法(JDK8)私有方法(JDK9)。
总结
接口就是一种公共的规范标准,只要符合规范标准,大家都可以通用。
Java中的接口更多的体现在对行为的抽象!
2.1.2 接口定义格式
接口用关键字interface修饰
public interface 接口名 {
//接口的成员列表:
// 公共的静态常量
// 公共的抽象方法
// 公共的默认方法(JDK1.8以上)
// 公共的静态方法(JDK1.8以上)
// 私有方法(JDK1.9以上)
}
2.1.3 接口的使用
接口是不能创建对象,必须有实现类才能使用,类实现接口用implements表示
public class 类名 implements 接口名 {}
注意: 接口的实现类必须重写接口中的所有的抽象方法,要么该类是一个抽象类
2.2 接口成员的特点
成员变量
只能是常量,默认修饰符:public static final
成员方法
只能是抽象方法,默认修饰符:public abstract
构造方法
没有,因为接口主要是扩展功能的,而没有具体存在
// 接口类
public interface Inter {
//接口只能是常量
//默认修饰符:public static final
public int num1 = 10;
public final int num2 = 20;
public static final int num3 = 30;
int num4 = 40;
//接口没有构造方法
// public Inter() {}
//接口中不能有方法主体
// public void show() {}
//默认修饰符:public abstract
public abstract void method1();
public void method2();
void show();
}
//子类可以是抽象类。但是意义不大
public abstract class InterImpl extends Object implements Inter {}
/**
* 字类是具体类,要实现接口中所有的抽象方法
* 所有类都默认继承Object类,Object类是所有类的超类
*/
public class InterImpl extends Object implements Inter {
public InterImpl(){
super();//所有super走得是object类
}
@Override
public void method1() {
System.out.println("实现类中的method1");
}
@Override
public void method2() {
System.out.println("实现类中的method2");
}
@Override
public void show() {
System.out.println("实现类中的show");
}
}
public class Test {
public static void main(String[] args) {
//接口不能实例化
// Inter i = new Inter();
//通过多态的方法实
Inter i = new InterImpl();
//访问成员变量
System.out.println(i.num1);
//接口的常量是不能修改的
// i.num1 = 100;
i.method1();
i.method2();
i.show();
}
}
2.2.1 接口的成员说明
在JDK8.0 之前,接口中只允许出现:
(1)公共的静态的常量:其中public static final可以省略
(2)公共的抽象的方法:其中public abstract可以省略
理解:接口是从多个相似类中抽象出来的规范,不需要提供具体实现
在JDK8.0 时,接口中允许声明默认方法和静态方法:
(3)公共的默认的方法:其中public 可以省略,建议保留,但是default不能省略
(4)公共的静态的方法:其中public 可以省略,建议保留,但是static不能省略
在JDK9.0 时,接口又增加了:
(5)私有方法
除此之外,接口中没有构造器,没有初始化块,因为接口中没有成员变量需要动态初始化。
2.3 类与类的关系
类与类:
继承关系,只能单继承,不能多继承,可以多层继承。
接口与接口:
继承关系,可以单继承也可以多继承。
public interface Sister extends Father,Mother
类与接口:
实现关系,可以单实现,也可以多实现。
public class Son extends Object implements Father,Mother
并且还可以在继承一个类的同时实现多个接口。
2.4 抽象类和接口的区别
A:成员区别
抽象类:
成员变量:可以变量,也可以常量
构造方法:有
抽象类不能实现化
成员方法:可以抽象,也可以非抽象
接口:
成员变量:只可以静态常量 可以省略 static final
构造方法:无
接口不能实例化
成员方法:只可以抽象 可以省略abstract
B:关系区别
类与类
继承,单继承, 多层继承
类与接口
实现,单实现,多实现
接口与接口
继承,单继承,多继承
C:设计理念区别
抽象类【共性功能】。
接口【扩展功能】。
2.5 接口小结
接口中只有常量和抽象方法
接口是没有静态代码块和构造方法的。
一个类的直接父类是唯一的,但是一个类可以同时实现多个接口。 单继承多实现
如果实现类所实现的多个接口当中,存在重复的抽象方法,那么只需要覆盖重写一次即可。
如果实现类没有覆盖重写所有接口当中的所有抽象方法,那么实现类就必须是一个抽象类。