今天内容安排:
1、随机点名器
2、超市购物小票方法封装
3、超市购物小票加入全天购物金额统计功能
简易计算器的演示
超市购物小票之前代码封装成方法的演示
超市购物小票全天购物总收入汇总的演示加入了角色的概念
今天开始使用Eclipse
01案例整体需求.avi
02方法定义.avi
03方法使用.avi
04数组简介.avi
01案例整体需求
* A: 案例整体需求
* a: 随机点名器需求
* 存储所有同学姓名
* 总览全班同学姓名
* 随机点名其中一人,打印到控制台
* b: 超市购物小票需求
* 将昨天的代码封装成方法
* c: 超市购物小票新需求
* 加入全天购物金额统计功能
* B: 知识点安排
* a: 数组
* b: 方法
02方法定义
* A: 随机点名器需求需求分析
* a: 为什么要使用方法
随机点名器明确地分为了三个功能。如果将多个独立功能的代码写到一起,则代码相对冗长,
我们可以针对不同的功能可以将其封装到一个方法中,将完整独立的功能分离出来。
* b: 为什么要使用数组
而在存储同学姓名时,如果对每一个同学都定义一个变量进行姓名存储,则会出现过多孤立的变量,
很一次性将全部数据持有。此时,我们可以使用数组解决多个数据的存储问题。
* B: 方法的定义及使用
* a: 方法(函数)的作用
* 将一个完整功能的代码组织成一个方法,在再次完成相同的功能时,
便可以直接以整体的方式调用该功能,而不再将具体实现过程再完整重复一遍。
* 总结一句话:提高代码的复用性
* b: 方法举例(main方法)
* 就是一个特殊的方法。作为程序入口,供JVM调用。
* 将不同功能定义成不同方法。供其他方法调用。
* 最先接触方法时,我们定义不同的方法,供main方法调用。
* c: 方法的定义格式
* 定义方法时明确: 需要的数据 回馈的数据
修饰符 返回值类型 方法名(类型 形式参数1,类型 形式参数1 ,…) {
执行语句;
return 返回值;
}
* 修饰符:目前一律使用public static
* 返回值类型:回馈数据的类型,如果没有用void代替
* return:用于返回要回馈的数据
* 方法名:方法的名称
* 参数类型:需要的数据的数据类型
* 参数:需要的数据
* d: 方法的使用
* 有回馈值:回馈值类型 回馈值 = 方法名(方法需要的数据) ;
* 无回馈值:方法名(方法需要的数据);
* 注意:由于这里使用public static修饰,所以,这里所有的方法均直接调用即可。
后期没有static则不可以如此调用
03方法使用
* A: 案例代码
/*
方法:一个完整功能的封装,即一个方法就是一个独立的功能。
方法定义:
定义位置:类中与其他方法并列
修饰符 返回值类型 方法名(数据类型 参数1,数据类型 参数2) {
功能逻辑
return 返回值;
}
方法的使用:
现阶段:在同一个类中,通过main方法,直接调用其他方法。
有返回值: 返回值类型 变量 = 方法名(实际参与计算的数据1,实际参与计算的数据1);
没有返回值:方法名(实际参与计算的数据1,实际参与计算的数据1);
求两个数的和
成员变量:定义在类中方法外,可以被类中所有方法所访问
*/
public class Demo01Method{
static int x = 120;
public static void main(String[] args) {
//方法的调用
int i = getSum(10,20);
System.out.println(i);
System.out.println(x);
System.out.println(getSum(100,20));
}
//求两个整数的和
public static int getSum(int a,int b) {
int sum = a+b;
System.out.println(x+"===============");
return sum;
}
}
04数组简介
* A: 数组简介
* a: 求多个数的和需求分析
*1: 求多个数的和时,需要一次性传入多个数字,而几个数字并不知道。
此时可以将方法所需参数设置为一个数组,只要接受一个数组即可,
将数组传入后,再通过数组操作所有数字。
*2: 方法参数:需要一个存放int值的数组
*3: 方法返回值:回馈的是求和结果,类型与数组中的数据相同
* b: 数组
*1: 作用
* 数组用来存储多个数值,通过索引管理。可以存储任意类型,但是一个数组中只能存储一种类型的多个数值。
*2:定义格式
* 数据类型[] 变量名 = new 数据类型[数据个数];或者
* 数据类型[] 变量名 = {数据, 数据, 数据, 数据};
* 如:int[] arr = new int[5];
String[] arr2 = {"我爱Java", "我喜欢Java", "我和Java在一起"};
*3: 使用格式
* 数组元素:数组变量名[索引]
* 获取数组长度:数组变量名.length
* c: 案例代码
/*
数组:用于存储数据的容器,使用索引管理容器内元素
数组也是一种数据类型,是一种引用数据类型
定义格式:
数据类型[] 变量名(数组名) = new 数据类型[数组长度];
数据类型[] 变量名(数组名) = {数据1,数据2,数据3,数据4};
使用格式:
访问元素指获取值、赋值
数组名[索引]
获取数组长度:length属性
*/
public class Demo02Array{
public static void main(String[] args) {
//定义数组:数组中存储我班同学的就业薪资
int[] salaryArray = {20000,300,1024,521};
//使用数组:为元素赋值,取元素值
//赋值
salaryArray[3] = 500000;
//获取值
int i = salaryArray[3];
System.out.println(i);
int i2 = salaryArray[1];
System.out.println(i2);
System.out.println(salaryArray[2]);
//获取数组长度
int length = salaryArray.length;
System.out.println(length);
//使用格式1完成与上例相同的数组
int[] salaryArray2 = new int[4];
salaryArray2[0] = 20000;
salaryArray2[1] = 300;
salaryArray2[2] = 1024;
System.out.println(salaryArray2[3]);
//int[] arr = null;
//System.out.println(arr.[1]);
//int a = null; 基本类型不能赋值为null
}
}
===================================第一个阶段=================================
05需要封装的方法分析.avi
06存储所有同学姓名方法实现.avi
07打印所有同学姓名.avi
08随机点名方法实现.avi
05需要封装的方法分析
* A: 需要封装的方法分析
* a: 存储所有同学姓名
* 方法参数类型:存储姓名的数组
* 方法返回值:无
* 录入所有同学姓名大致分为3步:
* 1 定义一个存放所有同学姓名的数组
* 2 方法中使用键盘录入逐个同学姓名
* 3 调用方法时传入数组,向数组中放入每次要存储的姓名
* b: 总览全班同学姓名
* 方法参数类型:存储姓名的数组
* 方法返回值:无
* 在完成所有人员姓名数据持有后,打印数组中数据,总览所有人员姓名。
* c: 随机点名
* 方法参数类型:存储姓名的数组
* 方法返回值:由数组中随机产生的姓名
* 使用随机数产生随机索引,使用随机索引拿出对应学生姓名。并返回该学生姓名。
06存储所有同学姓名方法实现
* A: 存储所有同学姓名方法实现
* 案例代码
/*
随机点名器:
随机点名器具备以下3个内容:
存储所有同学姓名
总览全班同学姓名
随机点名其中一人,打印到控制台
*/
import java.util.Scanner;
import java.util.Random;
public class RandomName{
public static void main(String[] args) {
//调用三个功能性方法
String[] students = new String[3];
System.out.println("开始为数组赋值");
//直接调用无返回值的方法
saveNames(students);
System.out.println("数组赋值结束");
}
//存储所有同学姓名
public static void saveNames(String[] names) {
Scanner sc = new Scanner(System.in);
//获取数组长度
int namesNumber = names.length;
//通过for循环依次访问到每一个元素
for(int i=0; i<namesNumber; i++) {
names[i] = sc.next();
}
}
}
07打印所有同学姓名
* A: 打印所有同学姓名
* 案例代码(方法)
//展示班级所有同学姓名
public static void printStudentNames(String[] names) {
//遍历数组
for(int i=0; i<names.length; i++){
String name = names[i];
System.out.println(name);
}
}
08随机点名方法实现
* A: 随机点名方法实现
* a: 案例代码(最终代码)
public class RandomName{
public static void main(String[] args) {
//调用三个功能性方法
String[] students = new String[3];
System.out.println("开始为数组赋值");
//直接调用无返回值的方法
saveNames(students);
System.out.println("数组赋值结束");
System.out.println(students[1]);
System.out.println("============================");
//直接调用无返回值的方法
printStudentNames(students);
System.out.println("============================");
//调用方法,返回随机人名,使用变量接收
String name = randomName(students);
System.out.println(name);
}
//存储所有同学姓名
public static void saveNames(String[] names) {
Scanner sc = new Scanner(System.in);
//获取数组长度
int namesNumber = names.length;
//通过for循环依次访问到每一个元素
for(int i=0; i<namesNumber; i++) {
names[i] = sc.next();
}
}
//展示班级所有同学姓名
public static void printStudentNames(String[] names) {
//遍历数组
for(int i=0; i<names.length; i++){
String name = names[i];
System.out.println(name);
}
}
//随机点名
public static String randomName(String[] names) {
//产生随机索引,范围为0~(names.length-1)
//创建随机数类对象
Random random = new Random();
//调用随机数方法,产生随机索引
int randomIndex = random.nextInt(names.length);
//从数组中获取随机索引对应的元素值
String name = names[randomIndex];
//返回该随机点名到的人名
return name;
}
}
=========================================第二阶段=============================================
09方法的详细介绍.avi
10数组的详细解释.avi
11数组的内存解释.avi
12超市购物小票代码回顾.avi
09方法的详细介绍
* A: 方法
* a: 定义
* 方法是对现实功能的一个抽象,便于对功能的复用。在一个类中可以有多个方法,多个方法是平等关系。main方法就是一个方法。
在C语言当中,相同的概念使用函数来命名。
* b: 定义格式
修饰符 返回值类型 方法名(类型 形式参数1,类型形式参数1 ,…) {
执行语句;
return 返回值;
}
* 修饰符:目前一律使用public static
* 返回值类型:
方法运行后返回的运算结果的数据类型
可以返回任意类型,包含基本数据类型与引用数据数据类型
如果没有返回值,则使用void
返回值类型是在方法定以前,设计这个方法时已经想好的。是功能的一部分
* return:
用于结束方法。
结束方法的同时如果定义的返回值类型不是void,则同时将结果返回给调用者。
当返回值类型为void时,return后可以不跟返回值,直接写return;也可以省略
* 返回值:
该方法运算的数值结果,该结果会通过return返回给调用者
有时结果运行后没有返回值。(买东西与买服务)
返回值的数据类型一定要与返回值类型统一
* 方法名:
方法的名称,区分不同方法的依据
定义符合小驼峰式 wordWordWord
* 参数类型:
是形式参数的数据类型
* 形式参数:
如数学计算,通过已知数计算结果。方法需要通过已知数组完成功能,形式参数就是接收”已知数据”的变量。
是一个变量,用于存储调用方法时传递给方法的实际数值。
定义符合小驼峰式 wordWordWord
是方法想顺利运行时,需要获取的数据
用于变量进行方法计算使用。
* c: 使用
* 对象名.方法名(对应参数)
* 方法必须先定义再使用
* 方法的定义顺序跟调用无关
* 方法不能嵌套定义,但是可以嵌套调用
* B: 方法重载
* a: 定义
* 在同一个类中,出现方法名相同而参数列表不同,这样定义方法叫做方法重载。
这样的设计优化了程序设计
* b: 注意事项
* 重载与返回值无关
* 重载与具体的变量标识符无关
* 重载只与方法名与参数名相关
* 重载方法方法名必须相同
* 重载方法参数必须不同
* 参数个数不同
* 参数类型不同
* 参数顺序不同
* c: 方法重载举例
* 如:求3个数,4个数的和
* 方法定义:与求两数逻辑类似,求3、4个数和的方法中中只有参数不同。方法名与求两数的方法名相同,三个方法互为重载关系
* public int add(int a,int b) {逻辑} //两个数加法
* public int add(int a,int b,int c) {逻辑} //三个数加法
* public int add(int a,int b,int c,int d) {逻辑} //四个数加法
* c: 使用
* 三个数求和、四个数求和
* 三个数与四个数求和思想与求两个数大致相同:
* 参数:需要3个或4个整数
* 返回值:回馈的是求和结果,类型与给予的数相同
* 但是在方法命名时,无论求多少个数的和,均是求和功能,在起名时可以起相同名称,这时便可以使用方法重载完成功能。
* d: 案例代码
public class Demo02MathTool {
public static void main(String[] args) {
int x = 10;
int y = 20;
int add = add(x,y);
System.out.println(add);
System.out.println(add(10,20,30));
System.out.println(add(10,20,30,40));
System.out.println(subtract(x,y));
System.out.println(multiply(x,y));
System.out.println(divide(x,y));
}
//求两个数的和
public static int add(int a,int b) {
// int sum = a + b;
// return sum;
return a + b;
}
//求三个数的和
public static int add(int a,int b,int c) {
int sum = a + b + c;
return sum;
}
//求四个数的和
public static int add(int a,int b,int c,int d) {
int sum = a + b + c + d;
return sum;
}
//求两个数的差
public static int subtract(int a,int b) {
return a - b;
}
//求两个数的积
public static int multiply(int a,int b) {
return a * b;
}
//求两个数的整除商
public static int divide(int a,int b) {
return a / b;
}
}
10数组的详细解释
* A: 数组详细解释
* a: 容器
* 将程序中可以临时存储数据的部分叫做容器,ava当中具有持有数据功能的容器中,数组是最基本的
* b: 数组的特点
* 数组是Java当中效率最快的容器
* 数组的长度是固定的,数组一旦被创建,长度永远不能被改变
* 数组中只能存储一种类型的数据
* c:数组的定义
* 数据类型[] 数组名 = new 数据类型[数组长度] ;
* 如:
int[] arr = new int[5];
int[] arr = new int[]{20,5,100,30,5}
int[] arr = {20,5,100,30,5}
int arr[] = new int[4];//c语言的定义格式
* d: 数组的使用
* 索引:数组底层是依次将数据进行编号后直接通过编号访问(线性序列)的。这个编号叫做索引。从0开始最大值为数组长度减1
* 数组名:代表数组的内存地址
* 数组元素:数组名[索引];
* e: 数组的注意事项
* 空指针异常(NullPointerException)
* 变量根本没有值
* 如定义了int a; int[] b;这里直接使用变量a和b,编译就报错
* 变量有值,但值为null
* 如int a = null; 编译失败,因为null只能赋值给引用数据类型
* int[] arr = null; 正常赋值,但是之后使用数组的任何属性和元素都会报出空指针异常
* 数组索引越界异常(ArrayIndexOutOfBoundsException)
* 当数组中不存在该索引却访问该索引时,出现数组索引越界异常
11数组的内存解释
* A: 引用数据类型数组内存图(详见day04_source文件夹中的"数组内存结构图_1.png"图片)
* a: 内存分区
* 寄存器:最快的存储区域直接与CPU打交道,是程序员无法控制的计算区域
* 堆栈:又叫栈,仅次于寄存器。用于存储局部变量
* 堆:通用内存池,用于存放所有引用数据类型对象。存储new出来的数组或对象,每个对象均有地址,且有默认初始化值。
* 方法区:面向对象部分讲解
* 本地方法区:和系统相关
* 常量存储区域:用于存放永远不会被改变的值
* b: 引用数据类型数组的内存结构图(图形见笔记目录下的数组内存结构图_1.png)
* int[] arr = new int[]{1,5,6,1,7};
* 引用变量:引用数据类型定义的变量(arr)存储在栈内存当中,这个arr变量叫做这个数组实例的引用变量。
* =:与数学当中的意义不同,是赋值的意思,并非相等。
* 真正的数组实例是通过new关键字创建出来,存储于堆内存中,并产生一个十六进制表示的内存地址0x1A29。
* 在数组创建期间,会将所有值默认初始化,再进行赋值。对于int型的数值,其默认值为0。
* 这个引用变量会指向这个数组的内存地址
换句话说:引用变量的值是这个数组实例的地址值
再换句话说:引用变量通过地址可以表示这个数组对象
12超市购物小票代码回顾
* A: 超市购物小票代码回顾
* a: 回顾之前的超市购物小票代码(理清思路)
=====================================第三阶段===================================
13成员变量简介.avi
14键盘录入数字方法封装.avi
15购买方法与打印小票方法封装.avi
16流水与总收入需求.avi
17流水与总收入方法实现.avi
18方法调用图及Eclipse简介.avi
13成员变量简介
* A: 购物小票封装方法需求
* 将超市购物小票案例中完成独立功能的代码逻辑分别封装成方法,比如:打印小票、购买流程、结账流程
* B: 成员变量
* 什么时候使用成员变量
* 当我们希望变量不只属于某个方法,而是属于整个类,这时可以将被所有方法共享的数据定在成员位置
* 定义位置
* 直接定义在类中方法外的变量,叫做成员变量。
* 作用域
* 定义在方法内,变量只在方法内起作用,而定义在类中,可以被本类中的所有方法访问
* C: 成员变量知识补充
* 如果将变量定义在方法内部的话,该变量的作用域只能在该方法内部,
其它方法不能使用,如果很多方法都要访问这些数据,就需要将这些数据定义在成员位置
* 前面的代码中所有变量都是用static修饰的为什么呢?因为main方法是static修饰的。这样main方法调用其它方法时,其它方法也必须是静态的,而静态方法访问属性时,属性也必须是静态的
静态的只能访问静态的
* 关于成员变量的其它知识在面向对象时会详细讲解
14键盘录入数字方法封装
* A: 键盘录入数字方法封装
* a: 录入数字方法代码
//键盘录入数字方法
public static int enterNumber() {
Scanner sc = new Scanner(System.in);
int enterNubmer = sc.nextInt();
return enterNubmer;
}
* b: 将Supermarket案例中所有用到sc.nextInt();的地方替换为enterNumber();
15购买方法与打印小票方法封装
* A: 购买方法与打印小票方法封装
* a: 因为要在多个方法中使用变量,所以需要将main方法中定义每个商品变量信息的代码提升到成员位置
//通过变量打印商品报价单
//定义每个商品的变量
static String slsName = "少林寺酥饼核桃"; //名称
static String slsID = "090115"; //编号
static double slsPrice = 15.5; //单价
static String slsUnit = "个"; //单位
static int slsNumber = 0; //数量
static double slsMoney = 0; //金额
static String skName = "皇家特供尚康杂粮牡丹饼(复合营养型)";
static String skID = "090027";
static double skPrice = 14.5;
static String skUnit = "个";
static int skNumber = 0;
static double skMoney = 0;
* b: 因为购买的动作在原来代码的case1之后,只需要将case1后的代码抽取出一个买方法buy即可
//购买方法
public static void buy(){
//打印商品报价单
System.out.println(" 欢迎光临");
System.out.println();
System.out.println("商品编号 商品名称 商品单价 商品计价单位");
System.out.println(slsID+" "+slsName+" "+slsPrice+" "+slsUnit);
System.out.println(skID+" "+skName+" "+skPrice+" "+skUnit);
//让用户输入每种货物的购买数量
//提示用户输入
System.out.println();
System.out.println("请输入您要购买的"+slsName+"数量:");
//使用用户输入的数量为已有的数量变量赋值
slsNumber = enterNumber();
slsMoney = slsPrice * slsNumber;
System.out.println("请输入您要购买的"+skName+"数量:");
//使用用户输入的数量为已有的数量变量赋值
skNumber = enterNumber();
skMoney = skPrice * skNumber;
}
* c: 因为打印小票的动作在原来代码的case2之后,只需要将case2后的代码抽取出一个买方法printReceipt即可
//打印小票的方法(结账方法)
public static void printReceipt(){
//票头
//直接字符串常量打印
System.out.println(" 欢 迎 光 临 ");
System.out.println(" 品名 售价 数量 金额");
System.out.println("-------------------------------------------------------");
//票体
//如果商品名称超过7个字,就截取前7个字+...
//使用if替换掉三元运算符的实现
//slsName的名字是否超过了7个字
if(slsName.length() > 7) {
//截取前7个字,连接...赋值给slsName
slsName = slsName.substring(0,7) + "...";
}
if(skName.length() > 7) {
//截取前7个字,连接...赋值给skName
skName = skName.substring(0,7) + "...";
}
System.out.println(slsName+"("+slsID+") "+slsPrice+" * "+slsNumber+" = "+slsMoney);
System.out.println(skName+"("+skID+") "+skPrice+" * "+skNumber+" = "+skMoney);
System.out.println("-------------------------------------------------------");
//票脚
//计算汇总的变量
int totalItemsNumber = 2; //商品项数
int totalNumber = slsNumber+skNumber; //商品件数
double totalMoney = slsMoney+skMoney; //商品总金额
//判断总金额和少林寺两种数据是否满足打折条件,满足就打折
/*
如果商品总价超过300元,打95折
如果商品总价超过600元,打9折
如果商品总价超过1000元,总价打8折
如果商品总价超过1000元,并且少林寺酥饼核桃购买超过30份, 则总价打8折后,立减20
*/
double afterTotalMoney = totalMoney;
//满300打95折
if(totalMoney>=300&&totalMoney<600) {
afterTotalMoney = totalMoney*0.95;
}else if(totalMoney>=600&&totalMoney<1000) {//满600打9折
afterTotalMoney = totalMoney*0.9;
}else if(totalMoney>=1000) {//满1000打8折
afterTotalMoney = totalMoney*0.8;
}
//满1000且少林寺超过30,打8折再立减20
if(totalMoney>=1000&&slsNumber>=30) {
afterTotalMoney = totalMoney*0.8-20;
}
System.out.println(totalItemsNumber+"项商品 共计:"+totalNumber+"件");
//在打印总金额时,超市显示四舍五入后的整数,不包含小数点,需要用到Math类四舍五入方法,及强制类型转换
afterTotalMoney = Math.round(afterTotalMoney);
System.out.println("总计:"+(int)afterTotalMoney+"元");
System.out.println("您真的太幸运了,本次打折活动为您节省了"+(totalMoney-(int)afterTotalMoney));
System.out.println("凭此小票换取发票");
//每次结账后,将数据重置
slsNumber = 0;
slsMoney = 0;
skNumber = 0;
skMoney = 0;
}
16流水与总收入需求
* A: 老板查询界面
* a: 这里将不再分老板和顾客角色,关于角色在就业班学习
* b: 在原有界面中增加查询流水和查询总收入的选择
* 查询流水
* 查询总收入
* c: 案例代码(这里只添加简单的代码,把架子搭起来,具体功能,下个视频讲)
将System.out.println("请选择您的操作:1代表开始购物、2代表结账(打印小票)、3直接退出"); 替换为
System.out.println("请选择您的操作:1:客户购买2:打印小票3:流水查询4:总收入查询5:退出查询");
将switch语句中原有的case 3改为case 5,并添加以下代码
case 3:
//调用流水查询方法
showFlow();
break;
case 4:
//调用总收入查询方法
showMoney4day();
break;
17流水与总收入方法实现
* A: 流水与总收入方法实现
* a: 流水实现
* 在成员位置定义数组记录流水,并定义计数器记录当前流水编号
//定义数组用来记录流水
static double[] flowData = new double[100];
static int indexNow = 0;
* 添加流水,在结账打印小票代码中,在打印结账信息代码之后,数据清零代码之前
//结账之后将本次结账的金额加入到流水数组中
flowData[indexNow] = afterTotalMoney;
indexNow++;
* 查询流水的方法(在case 3后调用该方法)
//定义展示流水方法
public static void showFlow(){
//成员位置流水数组的遍历
for(int i=0;i<indexNow; i++){
System.out.println(flowData[i]);
}
}
* 调用查询流水的方法
case 3:
//调用流水查询方法
showFlow();
break;
* b: 总收入方法实现
* 定义查询总收入的方法
//查询当日总收入
public static void showMoney4day() {
//将所有流水相加即可
//定义变量,记录总收入
double sum = 0;
for(int i=0;i<indexNow; i++){
sum = sum+flowData[i];
}
System.out.println("今天的总收入为:"+sum+"¥");
}
* 在case 4后调用查询总收入的方法
case 4:
//调用总收入查询方法
showMoney4day();
break;
18方法调用图及Eclipse简介
* A: 超市购物小票逻辑流程图
* a: 详见day04_source文件夹中的"超市购物小票逻辑流程图_3.png"图片
* B: Eclipse简介
* a: 安装Eclipse时要和jdk相对应
* 64位Eclipse->64位jdk
* 32位Eclipse->32位jdk
* b: 解压缩后直接使用,不用安装
* c: 使用步骤
* 开启,选择工作区
* 创建Java项目
* 在项目的src目录下创建java文件并编写代码