面向对象

Java 对象和类

Java 作为一种面向对象的编程语言,支持以下基本概念:

1、类(Class)

  • 定义对象的蓝图,包括属性和方法。
  • 示例:public class Car { ... }

2、对象(Object)

  • 类的实例,具有状态和行为。
  • 示例:Car myCar = new Car();

3、继承(Inheritance)

  • 一个类可以继承另一个类的属性和方法。
  • 示例:public class Dog extends Animal { ... }

4、封装(Encapsulation)

  • 将对象的状态(字段)私有化,通过公共方法访问。
1
2
private String name; 
public String getName() { return name; }

5、多态(Polymorphism)

  • 对象可以表现为多种形态,主要通过方法重载和方法重写实现。

  • 示例:

    • 方法重载:public int add(int a, int b) { ... }public double add(double a, double b) { ... }
    • 方法重写:@Override public void makeSound() { System.out.println("Meow"); }

6、抽象(Abstraction)

  • 使用抽象类和接口来定义必须实现的方法,不提供具体实现。

  • 示例:

    • 抽象类:public abstract class Shape { abstract void draw(); }
    • 接口:public interface Animal { void eat(); }

7、接口(Interface)

  • 定义类必须实现的方法,支持多重继承。
  • 示例:public interface Drivable { void drive(); }

8、方法(Method)

  • 定义类的行为,包含在类中的函数。
  • 示例:public void displayInfo() { System.out.println("Info"); }

9、方法重载(Method Overloading)

  • 同一个类中可以有多个同名的方法,但参数不同。
1
2
3
4
5
6
7
8
public class MathUtils {
public int add(int a, int b) {
return a + b;
}
public double add(double a, double b) {
return a + b;
}
}

下图中汽车类(class),而具体的每辆车为该汽车类的对象(object),对象包含了汽车的颜色、品牌、名称等。

null

构造方法

每个类都有构造方法。如果没有显式地为类定义构造方法,Java 编译器将会为该类提供一个默认构造方法。

在创建一个对象的时候,至少要调用一个构造方法。

构造方法的名称必须与类同名,一个类可以有多个构造方法。

1
2
3
4
5
6
7
8
9
10
11
12
public class Puppy {
// 默认构造器,没有参数
public Puppy() {
// 在这里可以添加初始化代码
}

// 带一个参数的构造器,参数为名字(String类型)
public Puppy(String name) {
// 在这里可以添加初始化代码,例如设置名字属性
this.name = name; // 假设有一个名为name的成员变量
}
}

下面的例子展示如何访问实例变量和调用成员方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class Puppy {
private int age;
private String name;

// 构造器
public Puppy(String name) {
this.name = name;
System.out.println("小狗的名字是 : " + name);
}

// 设置 age 的值
public void setAge(int age) {
this.age = age;
}

// 获取 age 的值
public int getAge() {
return age;
}

// 获取 name 的值
public String getName() {
return name;
}

// 主方法
public static void main(String[] args) {
// 创建对象
Puppy myPuppy = new Puppy("Tommy");

// 通过方法来设定 age
myPuppy.setAge(2);

// 调用另一个方法获取 age
int age = myPuppy.getAge();
System.out.println("小狗的年龄为 : " + age);

// 也可以直接访问成员变量(通过 getter 方法)
System.out.println("变量值 : " + myPuppy.getAge());
}
}
小狗的名字是 : tommy
小狗的年龄为 : 2
变量值 : 2

源文件声明规则

  • 一个源文件中只能有一个 public 类
  • 一个源文件可以有多个非 public 类
  • 源文件的名称应该和 public 类的类名保持一致。例如:源文件中 public 类的类名是 Employee,那么源文件应该命名为Employee.java。
  • 如果一个类定义在某个包中,那么 package 语句应该在源文件的首行。
  • 如果源文件包含 import 语句,那么应该放在 package 语句和类定义之间。如果没有 package 语句,那么 import 语句应该在源文件中最前面。
  • import 语句和 package 语句对源文件中定义的所有类都有效。在同一源文件中,不能给不同的类不同的包声明。

1. 类和对象

​ **面向过程 :**是一种以过程为中心的编程思想,实现功能的每一步,都是自己实现的

​ **面向对象 :**是一种以对象为中心的编程思想,通过指挥对象实现具体的功能

1.1 类和对象的关系

客观存在的事物皆为对象 ,所以我们也常常说万物皆对象。

    • 类的理解
      • 类是对现实生活中一类具有共同属性和行为的事物的抽象
      • 类是对象的数据类型,类是具有相同属性和行为的一组对象的集合
      • 简单理解:类就是对现实事物的一种描述
    • 类的组成
      • 属性:指事物的特征,例如:手机事物(品牌,价格,尺寸)
      • 行为:指事物能执行的操作,例如:手机事物(打电话,发短信)
  • 类和对象的关系

    • 类:类是对现实生活中一类具有共同属性和行为的事物的抽象
    • 对象:是能够看得到摸的着的真实存在的实体
    • 简单理解:类是对事物的一种描述,对象则为具体存在的事物

1.2 类的定义

类的组成是由属性和行为两部分组成

  • **属性:**在类中通过成员变量来体现(类中方法外的变量)
  • 行为:在类中通过成员方法来体现(和前面的方法相比去掉static关键字即可)

类的定义步骤:

​ ① 定义类

​ ② 编写类的成员变量

​ ③ 编写类的成员方法

1
2
3
4
5
6
7
8
9
10
11
12
public class Student {
// 属性 : 姓名, 年龄
// 成员变量: 跟之前定义变量的格式一样, 只不过位置发生了改变, 类中方法外
String name;
int age;

// 行为 : 学习
// 成员方法: 跟之前定义方法的格式一样, 只不过去掉了static关键字.
public void study(){
System.out.println("学习");
}
}

1.3 对象的创建和使用

  • 创建对象的格式:
    • 类名 对象名 = new 类名();
  • 调用成员的格式:
    • 对象名.成员变量
    • 对象名.成员方法();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class TestStudent {
/*
创建对象的格式:
类名 对象名 = new 类名();
调用成员变量的格式:
对象名.变量名
调用成员方法的格式:
对象名.方法名();
*/
public static void main(String[] args) {
// 类名 对象名 = new 类名();
Student stu = new Student();
// 对象名.变量名
// 默认初始化值
System.out.println(stu.name); // null
System.out.println(stu.age); // 0

stu.name = "张三";
stu.age = 23;

System.out.println(stu.name); // 张三
System.out.println(stu.age); // 23

// 对象名.方法名();
stu.study();
// com.itheima.object1.Student@b4c966a
// 全类名(包名 + 类名)
System.out.println(stu);
}
}

1.4 案例-手机类的创建和使用

**需求 :**首先定义一个手机类,然后定义一个手机测试类,在手机测试类中通过对象完成成员变量和成员方法的使用

分析 :

  • 成员变量:品牌, 价格
  • 成员方法:打电话, 发短信
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Phone {
// 品牌, 价格
String brand;
int price;

// 打电话, 发短信
public void call(String name){
System.out.println("给"+name+"打电话");
}

public void sendMessage(){
System.out.println("群发短信");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class TestPhone {
public static void main(String[] args) {
// 1. 创建对象
Phone p = new Phone();
// 2. 给成员变量进行赋值
p.brand = "大米";
p.price = 2999;
// 3. 打印赋值后的成员变量
System.out.println(p.brand + "..." + p.price);
// 4. 调用成员方法
p.call("阿强");
p.sendMessage();
}
}

2. 对象内存图

2.1 单个对象内存图【理解】

  • 1590938666222

2.2 多个对象内存图【理解】

  • 1590938693756

  • 总结:

    多个对象在堆内存中,都有不同的内存划分,成员变量存储在各自的内存区域中,成员方法多个对象共用的一份

2.3 多个对象指向相同内存图【理解】

1590938711726

  • 总结 :

    当多个对象的引用指向同一个内存空间(变量所记录的地址值是一样的)

    只要有任何一个对象修改了内存中的数据,随后,无论使用哪一个对象进行数据获取,都是修改后的数据。

当堆内存的引用没有任何引用能找到它时,会被判定为垃圾对象,自动回收

  • 当执行s1.name=“播妞”时,其实就是通过s1找到对象的地址,再通过对象找到对象的name属性,再给对象的name属性赋值为播妞;
    null

类和对象的一些注意事项

第一条:一个代码文件中,可以写多个class类,但是只能有一个是public修饰,且public修饰的类必须和文件名相同。

1
2
3
4
5
6
//public修饰的类Demo1,和文件名Demo1相同
public class Demo1{

}
class Student{
}

第二条: 对象与对象之间的数据不会相互影响,但是多个变量指向同一个对象会相互影响。

s1和s2两个变量分别记录的是两个对象的地址值,各自修改各自属性值,是互不影响的。
null

s1和s2两个变量记录的是同一个对象的地址值,s1修改对象的属性值,再用s2访问这个属性,会发现已经被修改了。
null

3. 成员变量和局部变量

3.1 成员变量和局部变量的区别

  • **类中位置不同:**成员变量(类中方法外)局部变量(方法内部或方法声明上)
  • **内存中位置不同:**成员变量(堆内存)局部变量(栈内存)
  • **生命周期不同:**成员变量(随着对象的存在而存在,随着对象的消失而消失)局部变量(随着方法的调用而存在,醉着方法的调用完毕而消失)
  • **初始化值不同:**成员变量(有默认初始化值)局部变量(没有默认初始化值,必须先定义,赋值才能使用)

null

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class RunoobTest {
// 成员变量
private int instanceVar;
// 静态变量
private static int staticVar;

public void method(int paramVar) {
// 局部变量
int localVar = 10;

// 使用变量
instanceVar = localVar;
staticVar = paramVar;

System.out.println("成员变量: " + instanceVar);
System.out.println("静态变量: " + staticVar);
System.out.println("参数变量: " + paramVar);
System.out.println("局部变量: " + localVar);
}

public static void main(String[] args) {
RunoobTest v = new RunoobTest();
v.method(20);
}
}

运行以上代码,输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
成员变量: 10
静态变量: 20
参数变量: 20
局部变量: 10
public class Student {
//成员变量
String name;//姓名
String gender;//性别
int age;//年龄
//成员方法
//吃饭
public void eat() {
System.out.println("吃饭饭...");
}
//学习
public void study() {
System.out.println("学习面向对象的内容...");
}
//睡觉
public void sleep() {
System.out.println("睡觉觉...");
}
//自我介绍
public void showInfo() {
System.out.println("姓名: " + name + ", 性别: " + gender + ", 年龄: " + age);
}
}
//创建Student类的对象
Student stu = new Student();
System.out.println(stu);//地址值:com.itxg02.Student@1540e19d
//打印成员变量的默认值
System.out.println(stu.name);//打印对象stu的name属性值,默认值: null
System.out.println(stu.gender);//打印对象stu的gender属性值,默认值: null
System.out.println(stu.age);//打印对象stu的age属性值,默认值: 0

//给成员变量赋值
stu.name = "张三";
stu.gender = "男";
stu.age = 18;

//打印成员变量
System.out.println(stu);//地址值:com.itxg02.Student@1540e19d
System.out.println(stu.name);//打印对象stu的name属性值: 张三
System.out.println(stu.gender);//打印对象stu的gender属性值: 男
System.out.println(stu.age);//打印对象stu的age属性值: 18

//调用成员方法
stu.eat();
stu.showInfo();
stu.study();
stu.sleep();

4. 封装

  1. 封装概述是面向对象三大特征之一(封装,继承,多态)是面向对象编程语言对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界是无法直接操作的
  2. 封装原则将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问成员变量private,提供对应的getXxx()/setXxx()方法
  3. 封装好处通过方法来控制成员变量的操作,提高了代码的安全性把代码用方法进行封装,提高了代码的复用性

4.1 private关键字

(1)被private修饰的成员变量,只能在本类中直接使用,在其它类中不可以通过对象名.成员变量名的形式继续访问了

(2)被private修饰的成员方法,只能在本类中直接使用,在其它类中不可以调用了

​ 提供“get变量名()”方法,用于获取成员变量的值,方法用public修饰

​ 提供“set变量名(参数)”方法,用于设置成员变量的值,方法用public修饰

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
class Student {
//成员变量
String name;
private int age;

//提供“get变量名()”方法,用于获取成员变量的值,方法用public修饰
//提供“set变量名(参数)”方法,用于设置成员变量的值,方法用public

public int getAge() {
return age;
}

//提供get/set方法
public void setAge(int a) {
if(a<0 || a>120) {
System.out.println("你给的年龄有误");
} else {
age = a;
}
}

//成员方法
public void show() {
System.out.println(name + "," + age);
}
}
/*
学生测试类
*/
public class StudentDemo {
public static void main(String[] args) {
//创建对象
Student s = new Student();
//给成员变量赋值
s.name = "林青霞";
s.setAge(30);
//调用show方法
s.show();
}
}


/*
学生类
*/
class Student {
//成员变量
private String name;
private int age;

//get/set方法
public void setName(String n) {
name = n;
}

public String getName() {
return name;
}

public void setAge(int a) {
age = a;
}

public int getAge() {
return age;
}

public void show() {
System.out.println(name + "," + age);
}
}
/*
学生测试类
*/
public class StudentDemo {
public static void main(String[] args) {
//创建对象
Student s = new Student();

//使用set方法给成员变量赋值
s.setName("林青霞");
s.setAge(30);

s.show();

//使用get方法获取成员变量的值
System.out.println(s.getName() + "---" + s.getAge());
System.out.println(s.getName() + "," + s.getAge());

}
}

4.3 this关键字

概述 : this修饰的变量用于指代成员变量,其主要作用是(区分局部变量和成员变量的重名问题)

  • 方法的形参如果与成员变量同名,不带this修饰的变量指的是形参,而不是成员变量
  • 方法的形参没有与成员变量同名,不带this修饰的变量指的是成员变量

方法内部直接写变量名的访问规则

就近原则: 方法内部有,直接使用,方法内部没有,找成员变量

局部变量和成员变量同名时,访问规则?

1.直接写变量名: 代表的是局部变量

2.this.变量名: 代表的是成员变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Student {
private String name;
private int age;

public void setName(String name) {
this.name = name;
}

public String getName() {
return name;
}

public void setAge(int age) {
this.age = age;
}

public int getAge() {
return age;
}

public void show() {
System.out.println(name + "," + age);
}
}

4.4 this内存原理【理解】

this代表谁呢?

​ 哪个对象调用方法,方法内部的this就代表调用方法的那个对象

​ 简单来讲: 谁来调用我,我就代表谁

1590938942838

1590938969305

创建对象的过程:

​ 使用new关键字创建对象 + 调用构造方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/*
构造方法:
1.作用: 当我们使用new关键字创建对象后(成员变量都是默认值),
必须调用构造方法,完成对象成员的初始化工作
2.格式:
修饰符 构造方法名称(参数列表...){
方法体;
return ;//建议省略
}
3.格式解释:
(1)修饰符中没有static关键字,目前就认为是固定public
(2)没有返回值类型,连void都没有
(3)构造方法名称必须和类名保持一模一样
(4)参数列表根据需求确定
(5)方法体: 一般是用来完成成员变量的赋值的
(6)可以写return ;,建议省略
4.注意:
(1)自定义类时,如果一个构造方法都不写,JVM默认隐藏提供一个空参构造
(2)构造方法也是方法,可以重载
(3)自定义类时,只要自己定义一个构造方法,JVM就不再提供空参构造
5.注意:
set方法主要是完成对象的成员变量值的修改
构造方法主要是对象创建后,立刻马上给对象的成员变量初始化的
*/
public class Demo05Computer {
public static void main(String[] args) {
//创建Computer类的对象: 空参构造
Computer comp = new Computer();
//调用set方法给成员变量赋值
comp.setBrand("ThinkPad");
comp.setColor("黑");
comp.setPrice(16999);
comp.setSize(15.6);

System.out.println("品牌: "+comp.getBrand());
System.out.println("价格: "+comp.getPrice());
System.out.println("颜色: "+comp.getColor());
System.out.println("屏幕的尺寸: "+comp.getSize());

//调用成员方法
comp.powerOn();
comp.type();
comp.powerOff();

//创建Computer类的对象: 满参构造
Computer comp2 = new Computer("苹果",19999,"白",14.1);
}
}
public class Computer {
//成员变量private修饰
private String brand;//品牌
private int price;//价格
private String color;//颜色
private double size;//屏幕的尺寸

//空参构造方法
public Computer(){
System.out.println("空参构造方法被执行了....");
}

//满参构造
public Computer(String brand, int price, String color, double size) {
this.brand = brand;
this.price = price;
this.color = color;
this.size = size;
}

//半参构造: 用的不多
public Computer(String brand, String color) {
this.brand = brand;
this.color = color;
}

//生成get和set方法
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getSize() {
return size;
}
public void setSize(double size) {
this.size = size;
}

//成员方法
//(1)开机的方法
public void powerOn(){
System.out.println(size+"寸的"+brand+"品牌的"+price+"元的"+color+"色的笔记本电脑正在开机....");
}

//(2)敲击键盘
public void type(){
System.out.println(size+"寸的"+brand+"品牌的"+price+"元的"+color+"色的笔记本电脑练习打字....");
}

//(3)关机的方法
public void powerOff(){
System.out.println(size+"寸的"+brand+"品牌的"+price+"元的"+color+"色的笔记本电脑正在关机....");
}
}

5. 构造方法

5.1 构造方法的格式和执行时机

  • 格式注意 :
    • 方法名与类名相同,大小写也要一致
    • 没有返回值类型,连void都没有
    • 没有具体的返回值(不能由retrun带回结果数据)
  • 执行时机 :
    • 在创建对象时,会调用构造器。每创建一次对象,就会执行一次构造方法
    • 不能手动调用构造方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Student {
private String name;
private int age;

//构造方法
public Student() {
System.out.println("无参构造方法");
}

public void show() {
System.out.println(name + "," + age);
}
}
/*
测试类
*/
public class StudentDemo {
public static void main(String[] args) {
//创建对象
Student s = new Student();
s.show();
}
}

5.2 构造方法的作用

  • **构造器的应用场景?**其实构造器就是用来创建对象的。可以在创建对象时给对象的属性做一些初始化操作。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class Student {
/*
格式:

1. 方法名需要跟类名相同, 大小写也要一致
2. 没有返回值类型, 连void都没有
3. 没有具体的返回值(不能由return带回具体的结果)
*/

private String name;
private int age;

// 1. 如果一个类中没有编写任何构造方法, 系统将会提供一个默认的无参数构造方法
public Student(){}

// 2. 如果手动编写了构造方法, 系统就不会再提供默认的无参数构造方法了
public Student(String name, int age){
this.name = name;
this.age = age;
System.out.println("我是Student类的构造方法");
}

public void show(){
System.out.println(name + "..." + age);
}
}
1
2
3
4
5
6
7
8
public class TestStudent {
public static void main(String[] args) {
Student stu1 = new Student("张三",23);
stu1.show();

Student stu2 = new Student();
}
}

5.3 构造方法的注意事项

构造方法的创建 :

​ 如果没有定义构造方法,系统将给出一个默认的无参数构造方法

​ 如果定义了构造方法,系统将不再提供默认的构造方法

构造方法的创建 :

​ 如果没有定义构造方法,系统将给出一个默认的无参数构造方法如果定义了构造方法,系统将不再提供默认的构造方法

推荐的使用方式 :

​ 无论是否使用,都手动书写无参数构造方法,和带参数构造方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1.什么是构造器?
答:构造器其实是一种特殊的方法,但是这个方法没有返回值类型,方法名必须和类名相同。

2.构造器什么时候执行?
答:new 对象就是在执行构造方法;

如果没有定义构造方法,系统将给出一个默认的无参数构造方法
如果定义了构造方法,系统将不再提供默认的构造方法


3.构造方法的应用场景是什么?
答:在创建对象时,可以用构造方法给成员变量赋值

4.构造方法有哪些注意事项?
1)在设计一个类时,如果不写构造器,Java会自动生成一个无参数构造器。
2)一定定义了有参数构造器,Java就不再提供空参数构造器,此时建议自己加一个无参数构造器。

无论是否使用,都手动书写无参数构造方法,和带参数构造方法

5.4 实体JavaBean类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/*
JavaBean类: 封装数据
*/
public class Student {
private String name;
private int age;

public Student() {
}

public Student(String name, int age) {
this.name = name;
this.age = age;
}

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 void show(){
System.out.println(name + "..." + age);
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
public class TestStudent {
public static void main(String[] args) {
// 1. 无参数构造方法创建对象, 通过setXxx方法给成员变量进行赋值
Student stu1 = new Student();
stu1.setName("张三");
stu1.setAge(23);
stu1.show();

// 2. 通过带参数构造方法, 直接给属性进行赋值
Student stu2 = new Student("李四",24);
stu2.show();
}
}

实体类仅仅只是用来封装数据用的。

1
2
3
4
5
6
1.JavaBean实体类是什么?有啥特点
它需要私有化成员变量,有空参数构造方法、同时提供getXxx和setXxx方法;
JavaBean实体类仅仅只用来封装数据,只提供对数据进行存和取的方法

2.JavaBean的应用场景?
JavaBean实体类,只负责封装数据,而把数据处理的操作放在其他类中,以实现数据和数据处理相分离。

图书管理系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package com.zxq._07_图书管理系统;

public class Book {
private String id;
private String name;
private double price;

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 double getPrice() {
return price;
}

public void setPrice(double price) {
this.price = price;
}

public Book() {
}

public Book(String id, String name, double price) {
this.id = id;
this.name = name;
this.price = price;
}
public void show(){
System.out.println("编号:"+id+"\t书名:"+name+"\t价格:"+price);

}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package com.zxq._07_图书管理系统;

import java.util.Scanner;

/*
图书的管理系统类

可以管理多本图书

具备:
添加图书
查看图书

*/
public class BookSystemManager {

// 定义一个图书类型的数组属性,用于 保存所有的图书对象
private Book[] books = new Book[3];


private Scanner sc = new Scanner(System.in);

public void showMenu(){
System.out.println("-----------欢迎进入图书管理系统------------------");
while (true){
System.out.println("请选择您要执行的功能:");
System.out.println("1:添加图书:");
System.out.println("2:查看图书:");
System.out.println("0:退出系统:");
int a = sc.nextInt();
switch (a){
case 0 -> {
System.out.println("感谢您的使用,拜拜!");
return;
}
// 专门自定义一个添加图书的方法
case 1 -> addBook();
case 2 -> showBooks();
default -> System.out.println("输入有误,看准了,再输入!");
}
}

}

private void showBooks() {
int index = findIndex();
if(index == 0){
// 说明还没有数据
System.out.println("系统暂无数据,请先添加再查看!");
return;
}
System.out.println("----------------全部图书信息如下----------------");
for (Book book : books) {
// 面向 book对象,调用 show方法
if(book!= null){
book.show();
}
}
}

//添加图书的方法
private void addBook() {
// 先从数组中找一个空位置,用于保存图书,如果位置已经满了,则不存了,提示即可
int index = findIndex();
// 判断索引是否有效
if(index == -1){
System.out.println("系统已满,无法添加了!");
return;
}
System.out.println("请输入图书的编号:");
String id = sc.next();
System.out.println("请输入图书的名称:");
String name = sc.next();
System.out.println("请输入图书的价格:");
double v = sc.nextDouble();
// 创建图书对象
Book b = new Book(id,name,v);
// 将 b 对象,保存到 index 位置
books[index] = b;
}

private int findIndex() {
for (int i = 0; i < books.length; i++) {
if(books[i] == null){
return i;
}
}
return -1;
}

}

1
2
3
4
5
6
7
package com.zxq._07_图书管理系统;

public class TestManager {
public static void main(String[] args) {
new BookSystemManager().showMenu();
}
}