这里写目录标题
- 第一章 JAVASE简介
- 第二章 JAVASE基本语法
- 第三章 面向对象编程
- 第四章 面向对象三大特性
- 第五章 面向对象高级特性
- 第六章 JAVA API(application programming interface)
第一章 JAVASE简介
1.1 JAVA的起源
JAVA起源于Sun公司,1995年推出JAVA,1996年上市,2009年被甲骨文收购(Oracle)。
JAVA前身oak语言。
1.2 JAVA的研究领域
领域 | 版本 | 开发领域 |
---|---|---|
JAVASE | 标准版本 | 桌面级别(C/S) |
JAVAEE | 企业版本 | 企业级别(B/S) |
JAVAME | 微小版本 | 手机级别 |
1.3 JAVA的版本
JDK1.2 分领域,J2SE
JDK1.5 新增
JDK1.8 新增内容
JDK1.10+
1.4 JAVA的安装
jdk JAVA开发工具包
jre JAVA运行环境
jvm JAVA虚拟机
检测:cmd 进入DOS界面
java -version
1.5 JAVA语言优势
1. 跨平台(不受限于操作系统)
2. 面向对象的
3. 安全性,鲁棒性
4. 多线程,高并发
5. 健壮
1.6 JAVA语言缺点
1. 不适合游戏项目,不适合刻画图形界面
2. 运行速度慢
1.7 DOS的基本操作指令
1. 切换磁盘 E: D:
2. 查看内容 dir
3. 进入某文件夹 cd 文件夹
4. 回到上级 cd...
1.8 JAVA的运行机制(重点)
JAVA属于:半编译半解释
编译型:源程序需要完整编译过程,成功编译才能运行,C,JAVA
解释型:程序不需要完整编译,逐条解释,逐条运行
1.8.1 第一个JAVA源程序HelloWorld
创建JAVA文件:HelloWorld.java
public class HelloWorld{
public static void main(String[] args){
System.out.println("welcome to study JAVA!")
}
}
1.8.2 编译和运行
DOS操作:
配置JAVA环境变量:
复制路径: C:\Program Files\Java\jdk1.8.0_121\bin;
环境变量 : path 粘贴
编译JAVA文件 javac 文件名.拓展名
运行JAVA文件 java 文件名
1.8.3 开发工具
1. 记事本
2. Eclipse
3. IDEA
1.8.4 Eclipse使用过程
1.创建项目 项目名字: 避开汉字,字母数字_构成,数字不开头 New > JAVA Project
2.创建类 src下 New > class
3.编辑源代码
4.ctrl+S 自动编译
5.run 运行
总结:
alt + / (联想键,提示键)
ctrl + F11 (运行)
ctrl+ / (注释代码/反注释)
1.8.5 JAVA中的注释
注释不会编译和运行,用来提示代码。开发中,一定要写注释。
1. 单行注释 // ctrl + /
2. 多行注释 /* */ ctrl+shift + / ctrl+shift + \
3. 文档注释 /** */ 标注类上方,声明作者,时间,目的...
文档注释
/**
*
* @author yushuang
* @since 1.0
* @version 2.0
* 2022-10-18
* 第一个JAVA源程序
*/
单行注释
//
多行注释
/*
*/
1.8.6 第一个源程序解析
注意事项:
- JAVA命名要求高
- JAVA强类型语言,明确区分大小写
- JAVA区分单双引号‘’ “”
- 拓展名 .java
解析:
1.关键字
关键字(保留字): 特殊用法的单词,均小写
public 公开的,当前类是公共使用的
class 定义类 ,类是JAVA源程序的最小构成单元,一个文件多个类,只能一个添加public的类,该类名和文件名相同
2.类名(自定义的)
1. 字母,数字 _ $ 构成, 不能数字开头
2. 不能是关键字
3. 首字母大写,复合单词每个都大写 如 HelloWorld ; Teacher
4. 有含义,避开汉字 LaoShi
3.语句块
{ 语句块的开始
} 语句块结束
规范: 遇到{退格} source > format
4.主方法
public static void main(String[] args){
}
JAVA 程序的入口,程序从主方法运行,固定的,主方法写在public修饰的类中,一个至少一个主方法
main alt /
5.输出语句
System.out.println("欢迎学习JAVA");
1. 每个语句结束 ;
2. "" 字符串,原样打印
3. print() 不换行 println() 输出并换行
6.JAVA中 + 号
1.加法 两端都是数字
2 拼接 两端有任意一端是“”, 拼接,形成 “”
关键字:
第二章 JAVASE基本语法
基本语法的内容写在主方法语句块{ }中。
语句块的构成:
1. 变量和常量 替换值的灵活的量
2. 数据类型
3. 运算符
4. 表达式
5. 语句(分支,循环)
2.1 变量和常量
变量 | 常量 | |
---|---|---|
含义 | 可以改变的量,替换所有的值 | 不可变的值 |
声明 | 数据类型 变量名 [= 初始值]; | final 数据类型 常量名 [= 初始值] |
命名 | 字母 数字 _ $ 构成,不能以数字开头,小写或驼峰xXXX 如age,stuNo |
变量的声明:
数据类型 变量名; //没有初始值的变量
数据类型 变量名 = 初始值; //有初始值的变量
//int 整数型
//=赋值 右边的值给左边的变量赋值
数据类型 变量名1 = 初始值,变量名2 = 初始值; //一起声明
public class TestFinal2 {
public static void main(String[] args) {
//定义变量 半径4
int r = 4;
//圆周率 PI double 3.14
final double PI = 3.1415926;
//输出圆的周长2Πr
double c = 2 * PI * r ;
System.out.println("周长:" + c);
}
}
总结:
1.变量的值任意改变,取最后的赋值
2.变量不可以重复声明
3.常量定义值后不能改
//常量
final int YEAR ;
//一旦定义不能改变
YEAR = 366;
//YEAR = 365; 不能改值
2.2 数据类型
两大类:
1.基本数据类型 四种八个
整数型 byte short int long
浮点型 float double
字符型 char
布尔型 boolean
2.引用数据类型
数组,类,接口,枚举,注解(特殊的字符串String "")
2.2.1 整数型
数据类型:用来决定变量所属类型,所占空间大小。
计算机存储:二进制(0和1),每个8比特位 = 1字节
0000 0010
1K = 1024 字节
1M = 1024 K
1G = 1024M
整型:存储的数字中整数。
含义 | 字节 | 位数 | 范围 | |
---|---|---|---|---|
byte | 字节型 | 1 | 8 | -128 ~ 127 |
short | 短整型 | 2 | 16 | -32768 ~ 32767 |
int | 整型 | 4 | 32 | -2147483648 ~ 2147483647 |
long | 长整型 | 8 | 64 | -2的63 ~ 2的63 - 1 |
注意:
对于JAVA中的数值,整数long型,必须在后面L或l,否则默认为int。
public class TestType_1 {
public static void main(String[] args) {
byte b = -128;
b = 127;
//b = 128;
short s = 32767;
s = -32768;
//s = 32769;
int i = -2147483648;
i = 2147483647;
long l = 2147483648L ;
l = -2147483649l;
}
}
2.2.2 浮点型
浮点型:存储的数字中小数。
含义 | 字节 | 位数 | 范围 | |
---|---|---|---|---|
float | 单精度浮点 | 4 | 32 | IEEE,大于long |
double | 双精度浮点 | 8 | 64 | IEEE,大于float |
注意:
对于JAVA中的数值,小数型默认为double,为了区分单精度需要添加F或f,double型可以添加D或d,也可以省略。
//账户余额
float balance = 200.5f;
//余额增加20000
balance = balance + 20000;
//体重
double weight = 150.88D;
范围顺序:byte < short < int < long < float < double
2.2.3 类型转换
1.自动转换
大类型 = 小类型;
2.强制转换
小类型 = (小类型)大类型;
public class TestType_3 {
public static void main(String[] args) {
short s = 10;
int a = 20;
long l = 30l;
//自动转换
float f = l;
double d = a;
double d2 = 38.56;
//强制转换,将小数变整数
a = (int)d2;
s = (short)f;
System.out.println(d);
//38
System.out.println(a);
}
}
总结:
小数取整:int a = (int)12.56;
2.2.4 字符型
char类型,存储一个字符(一个字母,一个汉字)
'a'
'中'
'9'
'男'
无符号
含义 | 字节 | 位数 | 范围 | |
---|---|---|---|---|
char | 字符型 | 2 | 16 | 0 ~ 65535 |
JAVA的编码机制:
UTF-8(unicode) , 全球统一编码。
字母和数字对应的:
ASCII 基础编码, 128位 (键盘每个符号对应一个数字码)
GB2312 中文多
需要记:
a-z (97 ~ 122)
A-Z (65 ~ 90 )
0-9 (48 ~ 57)
public class TestChar2 {
public static void main(String[] args) {
System.out.println(2 + 2);
System.out.println(2 + "2");
System.out.println(2 + '2');
System.out.println("2" + '2');
}
}
总结:
char 和数字类型 byte < short (char) < int < long < float < double
char可以和其他数值型做类型转换
转义字符:\
转义 | |
---|---|
\n | 换行 |
\t | 退格 |
\\ | 转义\ |
\’ | 转义’ |
\u0000 | 空字符 |
2.2.5 布尔型
boolean,用于做逻辑判断的数据类型:只有两个值,有默认值,false。占1bit。(内存中 0 真 1 假)
//true 真
//false 假
boolean b = true;
b = false;
注意:
1.boolean不可以和其他数据类型做转换
2.boolean作为逻辑条件出现,用来做条件判断
其他: 计算机四种进制 :二进制 八进制 十进制 十六进制
八进制:0开头(0~7)
十六进制:0x开头(0~9 A~F)
public class TestOther {
public static void main(String[] args) {
int a = 12; //十进制 2 * 1 + 1 * 10
a = 071; //八进制 1* 1 + 7*8 = 57
a = 0xFF; //十六进制 15* 1 + 15*16 = 255
System.out.println(a);
}
}
2.3 运算符
运算符 | 符号 |
---|---|
算术运算符 | + - * / % ++ – |
比较运算符(关系运算符) | > < >= <= != == |
逻辑运算符 | && || ! & | ^ >> << |
条件运算符(三目运算符) | ? : |
赋值运算符 | = |
前提:(int < double)
1. 变量做运算,一定取出现过的最高类型
2. 变量做过运算,数据类型不能低于int
//int a = 10;
//double b = 5.2;
//double res = a + b;
//System.out.println(res);
byte b1 = 10,b2 = 20;
byte b3 = (byte)(b1 + b2);
2.3.1 算术运算符
运算符 | 用法 |
---|---|
+ | 加法; 拼接 |
- | 减法,负的 |
* | 乘法 |
/ | 除法:两侧都是整数,结果只能是整的(向下取整),两侧有一侧是浮点,才是获得小数 |
% | 余数:能不能整除,判断奇数偶数 |
++ | 自加1,单目;a++;++a等价于 a = a + 1; |
- - | 自减掉1,单目 |
int a = 10;
a ++;
++ a;
System.out.println(a);//12
区别:
(当执行++ --时,没有其他运算,此时相同)
前置++ --: --a ++a
当有其他运算,先做++ – ,后做其他运算。
后置++ --: a-- a++
当有其他运算,先做其他运算,后做++ – 。
public class TestCom4 {
public static void main(String[] args) {
int a = 10;
int b = a ++; // b = a ; a ++ 11 10
//int b = ++ a;// a=11 b=11
System.out.println(a + "," + b);
}
}
int a = 10;
//System.out.println(a ++);//10
//System.out.println(a);//11
//System.out.println(++ a);//12
//22
System.out.println(a++ + ++a); //11+11
2.3.2 比较运算符
运算符 | 用法 |
---|---|
> | 大于 |
>= | 大于等于 |
< | 小于 |
<= | 小于等于 |
== | 等于 |
!= | 不等于 |
总结:
1.比较运算符的计算结果一定是布尔类型,结果通常作为判断条件
2.比较的变量的值
public class TestCom7 {
public static void main(String[] args) {
double d = 10.0;
float f = 10.0f;
char c = 10;
int i = 10;
System.out.println(d == c);//t
System.out.println(c == i);//t
System.out.println(f == i);//t
System.out.println(d == f);//t
}
}
2.3.3 逻辑运算符
用于连接条件的运算符,操作数必须是布尔类型。
运算符 | 用法 |
---|---|
&& | 短路与 |
& | 逻辑与 ; 二进制按位与 |
|| | 短路或 |
| | 逻辑或 ; 二进制按位或 |
! | 非 |
^ | 二进制按位异或 |
>> | 右移 |
<< | 左移 |
与:同真则真,一假则假 (双目)
&& 短路与: 当左侧操作数假的,右侧不执行
& 逻辑与: 都执行
或:同假则假,一真则真 (双目)
|| 短路或: 当左侧操作数真的,右侧不执行
| 逻辑或: 都执行
public class TestCom8 {
public static void main(String[] args) {
System.out.println(true && false);
System.out.println(true & true);
int a = 1 , b = 1;
//System.out.println(a ++ == 1 && ++ a == 1);
boolean boo = a ++ == 2 && --b == 0;
System.out.println(a + "," + b);
}
}
public class TestCom9 {
public static void main(String[] args) {
int a = 1, b = 1, c = 1;
boolean boo1 = a ++ == 1 && b ++ == 1 || c ++ == 1; // t 2 2 1
// t 3 2 1
boolean boo2 = a ++ == 2 || -- b == 1 && ++ c == 2;
System.out.println(boo1 + ", " + boo2);// true true
System.out.println(a + "," + b + "," + c);// 3 2 1
}
}
注意:
表达式中出现&&和|| ,&&级别更高
非>与>或
非: 真变假,假变真
public class TestCom10 {
public static void main(String[] args) {
System.out.println(!true);
System.out.println(!(5 > 3));
int a = 1, b = 1, c = 1;
System.out.println(++a == 1 && b ++ == 1 || --c == 0);
System.out.println(a + "," + b + "," + c);
}
}
位运算:
public class TestCom11 {
public static void main(String[] args) {
System.out.println(true & false);// 一假则假
System.out.println(2 & 3);//位运算
//0000 0000 0
//0000 0001 1
//0000 0010 2
//0000 0011 3
//有一个是0 就是0 同为1 1
//0000 0010
System.out.println(true | false);// 一真则真
System.out.println(2 | 3);//位运算
//0000 0010 2
//0000 0011 3
//有一个是1 是1 同0才是0
//0000 0011 3
//0000 0010 2
//0000 0011 3
//0000 0001 1
//相同为0 不同为1
System.out.println(2 ^ 3); // 按位异或
}
}
位移运算( 计算机中最快的方式: 2变16)
//左移 << n位 乘以2的n次幂
0000 0010
0000 0100
0000 1000 8
2 << 2 == > 2 * 4 = 8
//右移 >> n位 除以2的n次幂
System.out.println(2 << 3); // 2 * 8
System.out.println(32 >> 2); // 32 / 4
2.3.4 条件运算符
三目运算符(三个操作数),根据条件判断执行运算。
结果 = 操作数1(布尔类型) ? 操作数2 : 操作数3 ;
根据操作数1
真的 执行结果为操作数2
假的 执行结果为操作数3
//System.out.println(5 > 3 ? "是" : "不是");//是
//取出现过的最高数据类型
//System.out.println(12 % 5 == 1 ? 12.0 : 5);//5.0
//double d = 12 % 5 == 1 ? 12.0 : 5;
//定义三个变量
int a = 13, b = 45 , c = 45;
//获得三个变量的最大值()
//获得a和b的最大值
int max = a > b ? a : b;
max = max > c ? max : c;
//输出最大值
System.out.println("max=" + max);
2.3.5 赋值运算符
除去++ — 后置情况外,赋值运算符最后做。 右向左执行。
运算符 | 用法 |
---|---|
= | 赋值 |
+= | 联合运算的赋值; a+= 10 ; a = a + 10; 完成内部转化 |
-= | |
*= | |
/= | |
%= |
int a = 10;
a += 10; // a = a + 10;
byte b = 20;
//b = b + 10;
//内转
b += 10;
System.out.println(a);
总结:
优先级:
- 单目 - ! ++ – 前置
- 算术运算符
- 比较运算符
- 逻辑运算符 && > ||
- 三目运算符
- 赋值运算符
2.4 控制台接收
动态获取数据:
// 1. 创建接收的扫描工具Scanner是JAVA中的类
Scanner sc = new Scanner(System.in);
// 2. 导入Scanner所在包 ctrl+shift+o
import java.util.Scanner;
// 3. 接收
//整型
int age = sc.nextInt();
//浮点型
double score = sc.nextDouble();
//字符串
String name = sc.next();
public class TestScanner {
public static void main(String[] args) {
//控制台接收
//System.in
Scanner sc = new Scanner(System.in);
//控制台提示
System.out.println("请输入您的姓名:");
String name = sc.next();
System.out.println("请输入您的年龄:");
int age = sc.nextInt();
System.out.println("请输入您的成绩:");
double score = sc.nextDouble();
System.out.println(name + "您好,您的年龄是:" + age);
System.out.println(age > 18 ? "成年" : "未成年");
System.out.println(score >= 60 ? "及格" : "不及格");
sc.close();
}
}
2.5 语句
1. 顺序语句 : 从上往下,从左往右
2. 分支语句 : 根据条件,选择执行语句
3. 循环语句 : 根据条件,反复执行语句
2.5.1 分支语句
if-else 和 switch结构。
if-else结构的语法:
语法1:(一条分支)
if(布尔类型条件){
满足条件执行的语句;
}
语法2:(两条分支)
if(布尔类型条件){
满足条件执行的语句;
}else{
不满足条件执行的语句;
}
public class TestIf {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//控制台提示
System.out.println("请输入一个数字:");
int num = sc.nextInt();
if(num % 2 == 0) {
System.out.println("是偶数");
}else {
System.out.println("不是偶数");
}
}
}
练习: 控制台接收数字,判断是否需要敲桌(包含7 或7倍数)
package demo;
import java.util.Scanner;
public class AA {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入数字");
int num = sc.nextInt();
if (num % 7 == 0 || num % 10 == 7 || num / 10 % 10 == 7) {
System.out.println("敲");
}
}
}
语法3:(多条分支)
if(布尔类型条件1){
满足条件执行的语句;
}else if(布尔类型条件2){
}else if(布尔类型条件3){
}...
else{
都不满足;
}
练习:判断星期
public class TestIf {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入星期几:");
int day = sc.nextInt();
if(day >= 1 && day <= 5) {
System.out.println("好好上课");
}else if(day == 6) {
System.out.println("认真自习");
}else if(day == 7) {
System.out.println("休息一天");
}else {
System.out.println("非法日期");
}
}
}
练习:控制台接收一个数字,判断该数字对于5,6整除,只能整除5 25,只能整除 6 36,同时 30,都不能 13
package demo;
import java.util.Scanner;
public class LianXi {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入数字");
int a = sc.nextInt();
//写法1
if(a % 5 == 0 && a % 6 != 0) {
System.out.println("只能整除5");
}else if(a % 6 == 0 && a % 5 != 0) {
System.out.println("只能整除6");
}else if(a % 5 == 0 && a % 6 == 0) {
System.out.println("同时整除");
}else {
System.out.println("都不能");
}
//写法2(把整除 5 6的特殊情况放到第一个判断)
if (a % 5 == 0 && a % 6 == 0) {
System.out.println("能同时整除");
} else if (a % 5 == 0) {
System.out.println("只能整除5");
} else if (a % 6 == 0) {
System.out.println("只能整除6");
} else {
System.out.println("都不能");
}
}
}
总结:
多条分支从上往下,多选一,条件之间并列,不能包含
练习:控制台接收三个变量按从下到大顺序输出
package demo;
import java.util.Scanner;
public class LianXi {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入三个数字");
int a = sc.nextInt();
int b = sc.nextInt();
int c = sc.nextInt();
//写法1
//定义临时变量用来做交换
int temp = 0;
if (a > b) {
//交换思想
temp = a;
a = b;
b = temp;
}
if (a > c) {
temp = a;
a = c;
c = temp;
}
if (b > c) {
temp = b;
b = c;
c = temp;
}
System.out.println(a + "<" + b + "<" + c);
}
}
//写法2
// int mid = 0;
// int max = (a > b ? a : b) > c ? (a > b ? a : b) : c;
// int min = (a < b ? a : b) < c ? (a < b ? a : b) : c;
// if (a != max && a != min) {
// mid = a;
// } else if (b != max && b != min) {
// mid = b;
// } else if (c != max && c != min) {
// mid = c;
// }
// System.out.println(min + "<" + mid + "<" + max);
// 写法3: 列举
// if (a > b) {
// if (b > c) {
// System.out.println(a + ">" + b + ">" + c);
// } else {
// System.out.println(a + ">" + c + ">" + b);
// }
// } else if (b > c) {
// if (a > c) {
// System.out.println(b + ">" + a + ">" + c);
// } else {
// System.out.println(b + ">" + c + ">" + a);
// }
// } else if (c > a) {
// if (a > b) {
// System.out.println(c + ">" + a + ">" + b);
// } else {
// System.out.println(c + ">" + b + ">" + a);
// }
// }
10.19作业
作业1:定义一个三位整数,获得每个位置上数字求和,Int a = 234; 打印 sum=2 + 3 + 4 = 9
package com.qf.homework;
import java.util.Scanner;
/**
* 1、定义一个三位整数,
* 获得每个位置上数字求和 Int a = 234;
* 打印 sum=2 + 3 + 4 = 9
*/
public class Work1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入三位数");
int a = sc.nextInt();
if (a >= 100 && a <= 999) {
int sum = 0;
int ge = a % 10;
int shi = a / 10 % 10;
// int shi = a % 100 / 10;
int bai = a / 100;
sum = ge + shi + bai;
System.out.println("sum=" + sum);
} else {
System.out.println("不是三位数");
}
}
}
作业2:华氏温度转换为摄氏温度(控制)转换公式: c= 5 / 9 (F – 32)
package com.qf.homework;
import java.util.Scanner;
/**
* 2、华氏温度转换为摄氏温度(控制) 转换公式: c= 5 / 9 (F – 32)
*/
public class Work2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入华氏温度");
int f = sc.nextInt();
double c = 5 / 9.0 * (f - 32);
System.out.println(c);
}
}
作业3:(基本类型的运算)⼀家商场在举⾏打折促销,所有商品都进⾏8 折优惠。⼀位程序员把这个逻
辑代码写成:
short price = …; // 先计算出原价
short realPrice = price * 8 / 10; //再计算出打折之后的价格
问:
1 这段代码是否正确?
2 如果正确,假设price 为100,那计算之后的realPrice值为多少?
3 如果不正确,应该怎么改正?
package com.qf.homework;
/**
* 3、(基本类型的运算)⼀家商场在举⾏打折促销,
* 所有商品都进⾏8 折优惠。
* ⼀位程序员把这个逻 辑代码写成:
*
* short price = ...;
* 先计算出原价 short realPrice = price * 8 / 10;
* 再计算出打折之后的价格
*
* 问: 1 这段代码是否正确?
* 2 如果正确,假设price 为100,
* 那计算之后的realPrice值为多少?
* 3 如果不正确,应该怎么改正?
*
*/
public class Work3 {
public static void main(String[] args) {
// 数量
int count = 2;
// 单价
short price = 100;
// 错误
// short realPrice = (short) (price * 8 / 10.0);
// 改正
double realPrice = price * 8.0 / 10;
// 布尔类型变量,决定是否是vip
boolean vip = true;
// 判断是vip
if (vip) {
System.out.println("total=" + realPrice * count);
} else {
System.out.println("total=" + price * count);
}
}
}
作业4:接收三个变量代表三角形三边,判断是否可以构成三角形(是/否)(任意两边之和大于第三边)
package com.qf.homework;
import java.util.Scanner;
/**
* 4、 接收三个变量代表三角形三边,
* 判断是否可以构成三角形(是/否)
* (任意两边之和大于第三边)
*/
public class Work4 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入三角形的三条边");
int a = sc.nextInt();
int b = sc.nextInt();
int c = sc.nextInt();
// 先判断是否构成三角形
if (a + b > c && a + c > b && b + c > a) {
System.out.println("构成三角形");
} else {
System.out.println("不构成三角形");
}
}
}
作业5:接收一个年份,判断是否是闰年(能被4整除 不能被100整除或直接整除400)
package com.qf.homework;
import java.util.Scanner;
/**
* 接收一个年份,
* 判断是否是闰年 (能被4整除 不能被100整除或直接整除400)
*/
public class Work5 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入年份");
int year = sc.nextInt();
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
System.out.println(year + "是闰年");
} else {
System.out.println(year + "不是闰年");
}
}
}
作业6:接收变量a和b 代表矩形的宽高,获得矩形的周长和面积
package com.qf.homework;
import java.util.Scanner;
/**
* 6接收变量a和b 代表矩形的宽高,获得矩形的周长和面积
*/
public class Work6 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入两个数字");
int a = sc.nextInt();
int b = sc.nextInt();
int zc = a * b * 2;
int mj = a * b;
System.out.println("矩形的周长为:" + zc + "\n矩形的面积为:" + mj);
}
}
作业7:接收三个变量,利用if-else获得三个变量的最大值
package com.qf.homework;
import java.util.Scanner;
/**
* 7 接收三个变量,
* 利用if-else获得三个变量的最大值
*/
public class Work7 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入三个数字");
int a = sc.nextInt();
int b = sc.nextInt();
int c = sc.nextInt();
int max = 0;
if (a >= b && a >= c) {
max = a;
} else if (b >= a && b >= c) {
max = b;
} else {
max = c;
}
System.out.println("三个变量的最大值是:" + max);
}
}
switch结构:
switch(变量/表达式){
case 值1: {满足该值语句;break;}
case 值2: {满足该值语句;}
case 值3: {满足该值语句;}
...
default : {都不满足;}
}
注意:
- switch后变量类型要求: byte ,short, int ,char ,String(JDK7+) , 枚举型(JDK5+)
- case后的值也是以上类型,switch变量的值与case的值比较匹配,匹配到谁,执行哪个语句块
- case后值不能重复
- break可有可无,不加,依次向下执行,添加break,跳出整个switch
- default 默认的,都不匹配
package demo;
import java.util.Scanner;
public class LianXi {
public static void main(String[] args) {
int a = 60;
String light = "red";
switch (a) {
case 10:
System.out.println("10");
break;
case 20:
System.out.println("20");
break;
case 10 + 20:
System.out.println("30");
break;
// 不满足以上的条件就会运行default里面的语句
default:
System.out.println("40");
break;
}
}
}
练习:定义字符串类型交通灯,(switch)灯的颜色输出
package demo;
import java.util.Scanner;
public class LianXi {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入灯的颜色");
String light = sc.next();
switch (light) {
case "red":
System.out.println("红灯停");
break;
case "yellow":
System.out.println("黄灯缓行");
break;
case "green":
System.out.println("绿灯行");
break;
default:
System.out.println("灯坏了");
break;
}
}
}
练习:控制台接收一个学生成绩:(1~100分)(if),switch输出分数等级(90+A 80+B 70+C 60+D E)
package demo;
import java.util.Scanner;
public class LianXi {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入学生成绩");
int score = sc.nextInt();
if (score >= 1 && score <= 100) {
if (score >= 90 && score <= 100) {
System.out.println("A");
} else if (score >= 80 && score <= 90) {
System.out.println("B");
} else if (score >= 70 && score <= 80) {
System.out.println("C");
} else if (score >= 60 && score <= 70) {
System.out.println("D");
} else {
System.out.println("E");
}
} else {
System.out.println("成绩非法");
}
//写法2
// if (score >= 1 && score <= 100) {
// switch (score / 10) {
// case 9:
// case 10:
// System.out.println("A");
// break;
// case 8:
// System.out.println("B");
// break;
// case 7:
// System.out.println("C");
// break;
// case 6:
// System.out.println("D");
// break;
// default:
// System.out.println("E");
// break;
// }
// } else {
// System.out.println("成绩非法");
// }
}
}
2.5.2循环语句
根据一定的条件,反复运行代码的时候,使用循环语句。
循环的分类:
for循环
while循环
do-while循环
循环的四个组成部分:
1.初始值; 循环开始状态 1
2.循环条件; 循环执行的次数 <= 5
3.循环体; 反复执行代码 跑
4.迭代; 循环变更 1 > 2 2 > 3...
2.5.2.1 for循环语法规则:
for(初始值;循环条件;迭代){
循环体;
}
练习:循环打印盖家斌跑5圈
package demo;
import java.util.Scanner;
public class LianXi {
public static void main(String[] args) {
for (int i = 1; i <= 5; i++) {
System.out.println("盖家斌跑第" + i + "圈");
}
}
}
练习:打印1~100之间的奇数
package demo;
import java.util.Scanner;
public class LianXi {
public static void main(String[] args) {
for (int i = 1; i <= 100; i += 2) {
System.out.println(i);
}
// 写法2
// for (int i = 1; i <= 100; i++) {
// if (i % 2 != 0) {
// System.out.println(i);
// }
// }
}
}
练习:打印1~100之间的偶数
package demo;
import java.util.Scanner;
public class LianXi {
public static void main(String[] args) {
for (int i = 2; i <= 100; i += 2) {
System.out.println(i);
}
// 写法2
// for (int i = 1; i <= 100; i++) {
// if (i % 2 == 0) {
// System.out.println(i);
// }
// }
}
}
练习:1~100之间 逢七过
package demo;
import java.util.Arrays;
/**
* 逢七过
* */
public class Lx {
public static void main(String[] args) {
for (int i = 1; i <= 100; i++) {
if (i % 7 == 0 || i / 10 % 10 == 7 || i % 10 == 7) {
System.out.println("过");
continue;
}
System.out.println(i);
}
}
}
练习:键盘录入一个大于等于2的整数x,计算并返回x的平方根,结果只保留整数部分,小数部分将被舍去。 */
package demo;
import java.util.Scanner;
public class Lx {
public static void main(String[] args) {
// 分析:
// 平方根 16的平方跟4
// 4的平方根2
// 10
// 1*1 = 1 < 10
// 2*2 = 4 < 10
// 3*3 = 9 < 10
// 4*4 = 16 > 10
// 推断:10的平方根是在3~4之间。
// 20
// 1*1 = 1 < 20
// 2*2 = 4 < 20
// 3*3 = 9 < 20
// 4*4 = 16 < 20
// 5*5 = 25 >20
// 推断:10的平方根是在3~4之间。
// 在代码当中
// 从1开始循环,拿着数字的平方跟原来的数字进行比较
// 如果相等,那么当前数字就是平方跟
// 如果大于的,那么前一个数字就是平方根的整数部分
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个整数");
int num = sc.nextInt();
// 从1开始,num结束
for (int i = 1; i <= num; i++) {
// 用i*i再跟num进行比较
if (i * i == num) {
System.out.println(i + "就是" + num + "的平方根");
// 如果找到了平方根,循环就可以停止了,后面的数字就不需要再找了,提高代码的效率
break;
} else if (i * i > num) {
System.out.println((i - 1) + "就是" + num + "平方根的整数部分");
break;
}
}
}
}
经典问题之一:求和问题
练习:获得1-100累加和
package demo;
import java.util.Scanner;
public class LianXi {
public static void main(String[] args) {
// 定义sum变量用来做求和
int sum = 0;
for (int i = 1; i <= 100; i++) {
// 循环从1加到100
sum += i;
}
System.out.println("1~100的累加和:" + sum);
}
}
练习:1~ n 的累乘积,n是控制台接收的10以内数字
package demo;
import java.util.Scanner;
public class LianXi {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入数字");
int n = sc.nextInt();
// 判断接收进来的数字条件是否满足1~10
if (n >= 1 || n <= 10) {
// 定义mul变量用来做累乘积
int mul = 1;
for (int i = 1; i <= n; i++) {
// 假如接收的数字是5
// 循环就从1到累积乘到5
mul *= i;
}
System.out.println("mul=" + mul);
} else {
System.out.println("非法输入");
}
}
}
经典问题之二:计数问题
练习:统计1900-至今多少个闰年
package demo;
import java.util.Scanner;
public class LianXi {
public static void main(String[] args) {
int count = 0;
for (int i = 1900; i <= 2022; i++) {
if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) {
count++;
}
}
System.out.println("1900~2022年有:" + count + "个闰年");
}
}
练习:1-100 之间需要敲七的数字个数
package demo;
import java.util.Scanner;
public class LianXi {
public static void main(String[] args) {
int count = 0;
for (int i = 1; i <= 100; i++) {
if (i % 7 == 0 || i % 10 == 7 || i / 10 % 10 == 7) {
count++;
}
}
System.out.println("1~100之间敲七的个数有:" + count + "个");
}
}
经典问题之三:最大最小值问题
练习:控制台接收五个成绩,输出及格人数,最高分,总分
package demo;
import java.util.Scanner;
public class LianXi {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入五个成绩");
int max = 0;
int sum = 0;
int count = 0;
for (int i = 1; i <= 5; i++) {
int a = sc.nextInt();
sum += a;
if (a >= 60) {
count++;
}
if (a >= max) {
max = a;
}
}
System.out.println("及格人数:" + count);
System.out.println("最高分:" + max);
System.out.println("总分:" + sum);
}
}
总结:
(执行顺序)
1.初始值
2.循环条件
3.循环体
4.迭代
5.循环条件…(循环体 / 跳出循环)
package demo;
import java.util.Scanner;
public class LianXi {
public static void main(String[] args) {
int sum = 0;
int i = 0;
// i从1循环判断条件到5,满足条件i自加变成了6
// 发现i是6的时候不满足条件,是大于5的
// 所以不进入循环体
for (i = 1; i <= 5; i++) {
sum += i;
}
System.out.println(i); // 6
System.out.println(sum);// 15
}
}
10.20作业
作业1:定义三角形的三边 a b c,在能构成三角形的基础上,判断是何种三角形
等腰三角形
等边三角形
直角三角形 (勾股定理)
普通三角形
package com.qf.homework;
import java.util.Scanner;
/**
* 1. 定义三角形的三边 a b c,
* 在能构成三角形的基础上,
* 判断是何种三角形
* 等腰三角形
* 等边三角形
* 直角三角形 (勾股定理)
* 普通三角形
*/
public class Work1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入三角形的三条边");
int a = sc.nextInt();
int b = sc.nextInt();
int c = sc.nextInt();
// 判断是否是三角形
if (a + b > c && a + c > b && b + c > a) {
if (a == b && b == c) {
System.out.println("等边三角形");
} else if (a == b || b == c || a == c) {
System.out.println("等腰三角形");
} else if (a * a + b * b == c * c || a * a + c * c == b * b || b * b + c * c == a * a) {
System.out.println("直角三角形");
} else {
System.out.println("普通三角形");
}
System.out.println("三角形的周长=" + (a + b + c));
} else {
System.out.println("无法构成三角形");
}
}
}
作业2:接收一个分数,使用if分支判断分数的对应等级 A-E
package com.qf.homework;
import java.util.Scanner;
/**
* 2. 接收一个分数,使用if循环判断分数的对应等级 A-E
*/
public class Work2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入分数");
int score = sc.nextInt();
if (score >= 0 && score <= 100) {
if (score >= 90 && score <= 100) {
System.out.println("A");
} else if (score >= 80 && score <= 90) {
System.out.println("B");
} else if (score >= 70 && score <= 80) {
System.out.println("C");
} else if (score >= 60 && score <= 70) {
System.out.println("D");
} else {
System.out.println("E");
}
} else {
System.out.println("非法学分");
}
// 写法2
// if (score < 0 || score > 100) {
// System.out.println("成绩非法");
// } else {
// if (score >= 90) {
// System.out.println("A");
// } else if (score >= 80) {
// System.out.println("B");
// } else if (score >= 70) {
// System.out.println("C");
// } else if (score >= 60) {
// System.out.println("D");
// } else {
// System.out.println("不及格");
// }
// }
}
}
作业3-1:接收一个年份和月份,输出该年份该月份有多少天(switch)
package com.qf.homework;
import java.util.Scanner;
/**
* 接收一个年份和月份,输出该年份该月份有多少天
*/
public class Work3 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入年份");
int y = sc.nextInt();
System.out.println("请输入月份");
int m = sc.nextInt();
switch (m) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
System.out.println("31天");
break;
case 4:
case 6:
case 9:
case 11:
System.out.println("30天");
break;
case 2:{
if (y % 4 == 0 && y % 100 != 0 || y % 400 == 0) {
System.out.println("29天");
} else {
System.out.println("28天");
}
break;
}
default:
System.out.println("非法日期");
break;
}
}
}
作业3-2:接收一个年份和月份,输出该年份该月份有多少天(if)
package com.qf.homework;
import java.util.Scanner;
public class Work3_2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入年份");
int y = sc.nextInt();
System.out.println("请输入月份");
int m = sc.nextInt();
if (m > 12 || m < 1) {
System.out.println("月份不合法");
} else {
if (m == 2) {
if (y % 4 == 0 && y % 100 != 0 || y % 400 == 0) {
System.out.println("29天");
} else {
System.out.println("28天");
}
} else if (m == 4 || m == 6 || m == 9 || m == 11) {
System.out.println("30天");
} else {
System.out.println("31天");
}
// if (m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12) {
// System.out.println("31天");
// } else if (m == 4 || m == 6 || m == 9 || m == 11) {
// System.out.println("30天");
// }
}
}
}
作业4:定义一个变量 no=12345 ,pass = 12345 代表用户名和密码
控制台接收登录的账户和密码,与之比较,如果用户名错误 打印 账号错误,如果密码错误提示密码错误,否则提示 登录成功。
package com.qf.homework;
import java.util.Scanner;
/**
* 4.定义一个变量 no=12345 , pass = 12345
* 代表用户名和密码 控制台接收登录的账户和密码,
* 与之比较,
* 如果用户名错误
* 打印账号错误,
* 如果密码错误提示密码错误,
* 否则提示 登录成功。
*/
public class Work4 {
public static void main(String[] args) {
int no = 12345, pass = 12345;
Scanner sc = new Scanner(System.in);
System.out.println("请输入账号");
int a = sc.nextInt();
if (a == no) {
System.out.println("账号正确,请输入密码");
int b = sc.nextInt();
if (b == pass) {
System.out.println("密码正确,登陆成功");
} else {
System.out.println("密码有误,请重新输入正确的密码");
}
} else {
System.out.println("账号输入有误,请重新输入。");
}
}
}
作业5:输出10个斐波那契序列 1 1 2 3 5 8 13 21 ……
a b先定义好 Int a = 1,b =1;
package com.qf.homework;
/**
* 输出10个斐波那契序列
*1 1 2 3 5 8 13 21
*a b 先定义好
*int a = 1,b = 1
*/
public class Work5 {
public static void main(String[] args) {
// 先定义好a和b的初始值
// int a = 1,b = 1;
// 打印a和b的结果
// System.out.print(a + "\t" + b + "\t");
// 利用for循环从1到结束条件<=8
// for (int i = 1; i <= 8; i++) {
// 定义一个c变量存储a+b的和
// int c = a + b;//2 3 5 8 13 21 34
// 交换思想
// a = b;//1 2 3 5 8 13 21
// b = c;//2 3 5 8 13 21 34
// System.out.print(c + "\t");
// }
// 写法2
int a = 0, b = 1, c = 0;
// 循环斐波那契数列 并打印10个
for (int i = 1; i <= 10; i++) {
// 原b值暂存 c
c = b;
// 等于前两个数之和
b = a + b;
// 将原b值赋予a(即所有值向后顺推一位)
a = c;
System.out.print(a + " ");
}
// 写法3
// int a = 1, b = 1;
// for (int c = 1; c <= 5; c++) {
// System.out.print(" " + a + " " + b);
// a = a + b;
// b = a + b;
// }
}
}
作业6:.打印1-100之间的完全平方数(4 16 25…),每四个一换行
package com.qf.homework;
/**
* 打印1~100之间的完全平方数(4 16 25 ...)
* 每四个一换行
* 1*1==1
* 2*2==4
* 3*3==9
* 4*4==16
* 5*5==25 ...
*/
public class Work6 {
public static void main(String[] args) {
// 计数
int count = 0;
// 使用for循环条件开始是1~100结束
for (int i = 1; i <= 100; i++) {
// 获得完全平方数
int a = i * i;
// 完全平方数满足条件<=100
if (a >= 1 && a <= 100) {
// 打印
System.out.print(a + "\t");
count++;
if (count % 4 == 0) {
System.out.println();
}
}
}
}
}
作业7:用户输入任意两个数,输出这两个数的最大公约数和最小公倍数
package com.qf.homework;
/**
* 用户输入任意两个数,
* 输出这两个数的最大公约数和最小公倍数
* */
import java.util.Scanner;
public class Work7 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入两个数字");
int a = sc.nextInt();
int b = sc.nextInt();
// 将a,b中最小值存储到a
if (a > b) {
// 交换思想
int temp = a;
a = b;
b = temp;
}
// 找因子
// int max = 0;
// for (int i = 1; i <= a; i++) {
// if (a % i == 0 && b % i == 0) {
// max = i;
//
// }
// }
// 最大公约数
int max = 0;
for (int i = a; i >= 1; i--) {
if (a % i == 0 && b % i == 0) {
max = i;
break;
}
}
System.out.println("最大公约数:" + max);
// 最小公倍数
int min = 0;
for (int i = b; i <= a * b; i++) {
if (i % a == 0 && i % b == 0) {
min = i;
break;
}
}
System.out.println("最小公倍数:" + min);
// 最小公倍数:辗转相除 a * b / max
// System.out.println("最小公倍数:" + a * b / max);
}
}
作业8:打印1-1000之间的水仙花数(111+555+333 == 153)
package com.qf.homework;
package com.qf.homework;
/**
* 打印1~1000之间的水仙花数 (1*1*1+5*5*5+3*3*3==153)
*/
public class Work8 {
public static void main(String[] args) {
for (int i = 100; i < 1000; i++) {
// 个位
int a = i % 10;
// 十位
int b = i / 10 % 10;
// 百位
int c = i / 100;
// a的立方加b的立方加c的立方等于i
if (a * a * a + b * b * b + c * c * c == i) {
// 打印水仙花数
System.out.println(i);
}
}
}
}
2.6.1 双层(多层循环)
循环嵌套语法格式:
for(初始值 ; 循环条件 ; 迭代){
for(初始值 ; 循环条件 ; 迭代){
循环体;
}
}
练习:打印星星图形
package demo;
/**
****
****
****
****
* */
import java.util.Scanner;
public class LianXi {
public static void main(String[] args) {
//几行
for (int i = 1; i <= 4; i++) {
//重复星星
for (int j = 1; j <= 4; j++) {
System.out.print("*");
}
//换行
System.out.println();
}
}
}
形状问题:
package demo;
/**
*
**
***
****
*****
* */
import java.util.Scanner;
public class LianXi {
public static void main(String[] args) {
// 行
for (int i = 1; i <= 5; i++) {
// 每行的星星个数
for (int j = 1; j <= i; j++) {
System.out.print("*");
}
System.out.println();
}
}
}
package demo;
/**
*
***
*****
*******
* */
import java.util.Scanner;
public class LianXi {
public static void main(String[] args) {
// 行
for (int i = 1; i <= 4; i++) {
// 每行的星星个数
for (int j = 1; j <= 2 * i - 1; j++) {
System.out.print("*");
}
System.out.println();
}
}
}
package demo;
/**
*
***
*****
*******
* */
import java.util.Scanner;
public class LianXi {
public static void main(String[] args) {
// 行
for (int i = 1; i <= 4; i++) {
// 空
for (int k = 1; k <= 4 - i; k++) {
System.out.print(" ");
}
// 每行的星星个数
for (int j = 1; j <= 2 * i - 1; j++) {
System.out.print("*");
}
System.out.println();
}
}
}
数学算法问题:
练习:打印1-1000之间的完数 (完数 : 6 = 1 + 2 + 3)
package demo;
/**
打印1-1000之间的完数
完数 : 6 = 1 + 2 + 3
// 1 1-1000
// 2 找因子,求和
// 3 因子和 == 该数
* */
import java.util.Scanner;
public class LianXi {
public static void main(String[] args) {
for (int i = 1; i <= 1000; i++) {
// 每个数字的因子和
int sum = 0;
// 找i的因子
for (int j = 1; j < i; j++) {
if (i % j == 0) {
// System.out.println(j + "是" + i + "的因子");
sum += j;
}
}
// 和求完,判断是否相等
if (sum == i) {
System.out.println(i);
}
}
}
}
练习: 打印10-100之间的素数(只有1和本身两个因子)
思路1:
package demo;
/**
打印10-100之间的素数(只有1和本身两个因子)
* */
import java.util.Scanner;
public class LianXi {
public static void main(String[] args) {
for (int i = 10; i <= 100; i++) {
// 每个数字的因子个数
int count = 0;
// 找i的因子
for (int j = 1; j < i; j++) {
if (i % j == 0) {
// System.out.println(j + "是" + i + "的因子");
count++;
}
}
// 和求完,判断是否相等
if (count == 1) {
System.out.println(i);
}
}
}
}
思路2:
package demo;
/**
打印10-100之间的素数(只有1和本身两个因子)
* */
import java.util.Scanner;
public class LianXi {
public static void main(String[] args) {
for (int i = 10; i <= 100; i++) {
// 查是否还有其他
// 标记
boolean flag = true;
// 是否还有
for (int j = 2; j < i; j++) {
if (i % j == 0) {
// 是否还有因子,不是素数
flag = false;
break;
}
}
// 没有改
if (flag) {
System.out.println(i);
}
}
}
}
练习:键盘录入一个正整数x,判断该整数是否为一个质数。
package demo;
import java.util.Scanner;
public class Lx {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个整数");
int num = sc.nextInt();
// 标记
// true:是一个质数
// false:不是一个质数
// 表示最初就认为num是一个质数
boolean flag = true;
// 2.判断
// 写一个循环,从2开始判断,一直判断到num - 1 为止
// 看这个范围之内,有没有数字可以被num整除
for (int i = 2; i < num; i++) {
// i 依次表示这个范围之内的每一个数字
// num是否能被i整除就可以了
if (num % i == 0) {
flag = false;
// System.out.println(num + "不是一个质数");
break;
} // else {
// System.out.println(num + "是一个质数");
// }
}
// 只有当这个循环结束了,表示这个范围之内所有的数字都判断完了
// 此时才能断定num是一个质数
if (flag) {
System.out.println(num + "是一个质数");
} else {
System.out.println(num + "不是一个质数");
}
}
}
练习:生成一个1~100之间的随机数,使用程序实现猜出这个数字是多少。
package demo;
import java.util.Random;
import java.util.Scanner;
public class Lx {
public static void main(String[] args) {
// 注意点:
// 生成随机数的代码:int num = r.nextInt(100) + 1;
// 不能写在循环里面,否则每一次都会产生一个新的随机数
// 生成一个1~100之间的随机数
Random r = new Random();
int num = r.nextInt(100) + 1;
// 猜这个数字是多少
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("请输入数字");
int a = sc.nextInt();
if (a > num) {
System.out.println("猜大了");
} else if (a < num) {
System.out.println("猜小了");
} else {
System.out.println("猜中了");
break;
}
}
}
}
10.21作业
作业1:小九九的四种形状
打印小九九形状1
package com.qf.homework;
/**
* 打印小九九形状1
* */
public class Work4 {
public static void main(String[] args) {
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(j + "*" + i + "=" + i * j + "\t");
}
System.out.println();
}
}
}
打印小九九形状2
package com.qf.homework;
/**
* 打印小九九形状2
* */
public class Work5 {
public static void main(String[] args) {
for (int i = 1; i <= 9; i++) {
for (int k = 0; k <= 9 - i; k++) {
System.out.print("\t");
}
for (int j = 1; j <= i; j++) {
System.out.print(j + "*" + i + "=" + i * j + "\t");
}
System.out.println();
}
}
}
打印小九九形状3
package com.qf.homework;
/**
* 打印小九九形状3
*/
public class Work6 {
public static void main(String[] args) {
for (int i = 9; i >= 1; i--) {
for (int j = 1; j <= i; j++) {
System.out.print(j + "*" + i + "=" + i * j + "\t");
}
System.out.println();
}
}
}
打印小九九形状4
package com.qf.homework;
/**
* 打印小九九形状4
*/
public class Work7{
public static void main(String[] args) {
for (int i = 9; i >= 1; i--) {
for (int k = 1; k <= 9 - i; k++) {
System.out.print("\t");
}
for (int j = 1; j <= i; j++) {
System.out.print(j + "*" + i + "=" + i * j + "\t");
}
System.out.println();
}
}
}
作业2:图形
package com.qf.homework;
/**
*
***
*****
*******
*****
***
*
* */
public class Work2_1 {
public static void main(String[] args) {
// 行
for (int i = 1; i <= 4; i++) {
// 空格
for (int k = 1; k <= 4 - i; k++) {
System.out.print(" ");
}
// 星星
for (int j = 1; j <= 2 * i - 1; j++) {
System.out.print("*");
}
System.out.println();
}
for (int i = 3; i >= 1; i--) {
for (int k = 1; k <= 4 - i; k++) {
System.out.print(" ");
}
for (int j = 1; j <= 2 * i - 1; j++) {
System.out.print("*");
}
System.out.println();
}
}
}
package com.qf.homework;
/**
*
*****
* *
* *
* *
*****
* */
public class Work2_2 {
public static void main(String[] args) {
// for (int i = 1; i <= 5; i++) {
// if (i == 2 || i == 3 || i == 4) {
// System.out.print("* *");
// }
// for (int j = 1; j <= 5; j++) {
// if (i == 2 || i == 3 || i == 4) {
// System.out.print(" ");
// } else {
// System.out.print("*");
// }
// }
// System.out.println();
// }
//写法2
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 5; j++) {
if (i != 1 && i != 5 && j != 1 && j != 5) {
System.out.print(" ");
} else {
System.out.print("*");
}
}
System.out.println();
}
}
}
package com.qf.homework;
/**
******
******
******
* */
public class Work2_3 {
public static void main(String[] args) {
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 4 - i; j++) {
System.out.print(" ");
}
for (int k = 1; k <= 6; k++) {
System.out.print("*");
}
System.out.println();
}
}
}
作业3:李先生岁数的平方与他的夫人的岁数之和是1053,而他的夫人的岁数的平方与他的岁数之和是873,请编写程序计算李先生及其夫人的岁数各是多少。
package com.qf.homework;
/**
* 李先生岁数的平方与他的夫人的岁数之和是1053,
* 而他的夫人的岁数的平方与他的岁数之和是873,
* 请编写程序计算李先生及其夫人的岁数各是多少
*/
public class Work3 {
public static void main(String[] args) {
// 使用for循环假设条件是从1开始到100岁结束
// i代表丈夫的年龄
for (int i = 1; i <= 100; i++) {
// j代表夫人的年龄
for (int j = 1; j <= 100; j++) {
// 丈夫年龄的平方加上j等于1053,同时夫人年龄的平方加上i等于873
if (i * i + j == 1053 && j * j + i == 873) {
// 打印
System.out.println("丈夫的年龄" + i + "," + "夫人的年龄" + j);
}
}
}
}
}
作业4:实现百元买百鸡的问题:现在你手头有100元钱,要用这些钱来买100只鸡,公鸡3元一只,母鸡2元一只,小鸡0.5元一只,请问应该如何购买才能实现
package com.qf.homework;
/**
* 实现百元买百鸡的问题:
* 现在你手头有100元钱,
* 要用这些钱来买100只鸡,
* 公鸡3元一只,母鸡2元一只,小鸡0.5元一只,
* 请问应该如何购买才能实现
*/
public class Work4 {
public static void main(String[] args) {
int count = 0;
for (int x = 0; x <= 100; x++) {
for (int y = 0; y <= 100; y++) {
for (int z = 0; z <= 100; z++) {
if (x + y + z == 100 && 3 * x + 2 * y + 0.5 * z == 100) {
System.out.println("公鸡" + x + "," + "母鸡" + y + "小鸡" + z);
count++;
}
}
}
}
System.out.println("实现买鸡的方式有:" + count + "种");
}
}
练习:万年历写法1
package com.qf.demo;
import java.util.Scanner;
public class MyCalendar {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("请输入年份:");
int y = input.nextInt();
System.out.print("请输入月份:");
int m = input.nextInt();
// 总天数
int sum = 0;
// 1900.1.1 - year.1.1
for (int i = 1900; i < y; i++) {
if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) {
sum += 366;
} else {
sum += 365;
}
}
// year.1 ~ year .5
for (int i = 1; i < m; i++) {
if (i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10 || i == 12) {
sum += 31;
} else if (i == 4 || i == 6 || i == 9 || i == 11) {
sum += 30;
} else if (i == 2) {
if (y % 4 == 0 && y % 100 != 0 || y % 400 == 0) {
sum += 29;
} else {
sum += 28;
}
} else {
System.out.println("月份不正确");
}
}
int week = (sum + 1) % 7;
// System.out.println(week);
System.out.println("************************万年历*************************");
System.out.println("星期日\t星期一\t星期二\t星期三\t星期四\t星期五\t星期六");
// 打空格
// int count = 0;
for (int i = 1; i <= week; i++) {
System.out.print("\t");
// count++;
}
int day = 0;
switch (m) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
day = 31;
break;
case 4:
case 6:
case 9:
case 11:
day = 30;
break;
case 2:
if (y % 4 == 0 && y % 100 != 0 || y % 400 == 0) {
day = 29;
} else {
day = 28;
}
break;
default:
System.out.println("你输入的月份有误!");
}
// 打印的截至
for (int i = 1; i <= day; i++) {
System.out.print(i + "\t");
// count++;
week++;
if (week % 7 == 0) {
System.out.println();
}
}
System.out.println();
System.out.println("******************************************************");
}
}
练习:万年历写法2
package com.qf.demo;
import java.util.Scanner;
public class MyCalendar_2 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("请输入年份:");
int y = input.nextInt();
System.out.print("请输入月份:");
int m = input.nextInt();
// 总天数
// 1900.1.1 - year.1.1
int count = 0;
for (int i = 1900; i < y; i++) {
if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) {
count++;
}
}
count = (y - 1900) * 365 + count;
// year.1 ~ year .5
for (int i = 1; i < m; i++) {
switch (i) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
count += 31;
break;
case 4:
case 6:
case 9:
case 11:
count += 30;
break;
case 2:
if (y % 4 == 0 && y % 100 != 0 || y % 400 == 0) {
count += 29;
} else {
count += 28;
}
break;
default: {
System.out.println("你输入的月份有误!");
}
}
}
int week = (count + 1) % 7;
// System.out.println(week);
System.out.println("************************万年历*************************");
System.out.println("星期日\t星期一\t星期二\t星期三\t星期四\t星期五\t星期六");
// 打空格
// int count = 0;
for (int i = 1; i <= week; i++) {
System.out.print("\t");
// count++;
}
int day = 0;
switch (m) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
day = 31;
break;
case 4:
case 6:
case 9:
case 11:
day = 30;
break;
case 2:
if (y % 4 == 0 && y % 100 != 0 || y % 400 == 0) {
day = 29;
} else {
day = 28;
}
break;
default:
System.out.println("你输入的月份有误!");
}
// 打印的截至
for (int i = 1; i <= day; i++) {
System.out.print(i + "\t");
// count++;
week++;
if (week % 7 == 0) {
System.out.println();
}
}
System.out.println();
System.out.println("*******************************************************");
}
}
2.5.2.2 while循环语法规则:
初始值;
while(循环条件){
循环体;
迭代;
}
基本循环:
练习:求1-100和(while)
package com.qf.demo;
/**
* 求1~100的和
*/
public class LianXi {
public static void main(String[] args) {
// 求和变量
int sum = 0;
// 初始值
int i = 1;
// 循环条件
while (i <= 100) {
// 累加和
sum += i;
// 迭代
i++;
}
System.out.println(sum);
}
}
练习:判断 x 是不是回文数
package demo;
import java.util.Arrays;
public class Lx {
public static void main(String[] args) {
int x = 12345;
int num = 0;
int temp = x;
while (x != 0) {
int ge = x % 10;
num = num * 10 + ge;
x = x / 10;
}
System.out.println(num == temp ? "是回文数" : "不是回文数");
}
}
练习:给定两个整数,被除数,和除数,将两数相除,(要求不使用乘法,除法和%运算符),得到商和余数。
package demo;
import java.util.Arrays;
public class Lx {
public static void main(String[] args) {
// 被除数
int bcs = 100;
// 除数
int cs = 13;
// 记录相减了多少次
int count = 0;
// 条件:如果被除数大于等于除数那么就一直循环
while (bcs >= cs) {
bcs = bcs - cs;
// 减一次统计变量就自增一次
count++;
}
// 当循环结束之后dividend变量记录的就是余数
System.out.println("余数为" + bcs);
// 当循环结束之后,count记录的值就是商
System.out.println("商为" + count);
}
}
循环次数未知,外部决定:
package com.qf.demo;
import java.util.Scanner;
public class LianXi {
public static void main(String[] args) {
System.out.println("欢迎进入水果消消乐游戏");
System.out.println("要开始吗y/任意键退出");
Scanner sc = new Scanner(System.in);
// 初始值
String str = sc.next();
while (str.equals("Y") || str.equals("y")) {
// 循环体
System.out.println("噼里啪啦来一局");
System.out.println("...");
System.out.println("游戏结束");
// 迭代
System.out.println("再来一局?Y/任意键退出");
str = sc.next();
}
System.out.println("下次再来!!!");
}
}
while的死循环菜单程序:
package com.qf.demo;
import java.util.Scanner;
public class LianXi {
public static void main(String[] args) {
double balance = 5000;
Scanner sc = new Scanner(System.in);
System.out.println("欢迎进入到ATM系统");
// 菜单程序
while (true) {
System.out.println("1-存钱");
System.out.println("2-取钱");
System.out.println("3-查看余额");
System.out.println("4-退出系统");
System.out.println("请输入操作编号");
int opr = sc.nextInt();
if (opr == 1) {
System.out.println("请输入存款金额");
int money = sc.nextInt();
if (balance > 0 && balance % 100 == 0) {
balance += money;
System.out.println("存钱成功");
} else {
System.out.println("存钱失败");
}
} else if (opr == 2) {
System.out.println("请输入取款金额");
int money = sc.nextInt();
if (money > 0 && balance > money) {
balance -= money;
System.out.println("取钱成功");
} else {
System.out.println("取钱失败");
}
} else if (opr == 3) {
System.out.println("您的余额为:" + balance);
} else if (opr == 4) {
System.out.println("谢谢使用");
System.exit(0);
} else {
System.out.println("非法操作");
}
}
}
}
注意: for也可以死循环
for(;;){
}
10.24作业
作业:Shopping
package com.qf.homework;
import java.util.Scanner;
/**
* @version 1.0
* @author 86136
*
*/
public class Shopping {
public static void main(String[] args) {
// 一级菜单
Scanner sc = new Scanner(System.in);
System.out.println("-----------欢迎进入到我行我素购物系统1.0版本-------------------");
String no = "admin";
String pass = "admin";
int credits = 2000;
while (true) {
System.out.println("1-登录");
System.out.println("2-退出");
System.out.println("请输入操作编号:");
int opr1 = sc.nextInt();
if (opr1 == 1) {
// 登录
System.out.println("请输入用户账户:");
String yNo = sc.next();
if (no.equals(yNo)) {
// 判断密码
System.out.println("请输入密码:");
String yPass = sc.next();
if (pass.equals(yPass)) {
// 登录成功
System.out.println("登录成功,你好" + no + "当前积分:" + credits);
// 二级菜单
// 定义商品变量
String name1 = "T恤", name2 = "网球鞋", name3 = "网球拍";
double price1 = 245, price2 = 570, price3 = 320;
//折扣
double dis = 1;
if (credits >= 8000) {
dis = 0.6;
} else if (credits >= 4000) {
dis = 0.7;
} else if (credits >= 2000) {
dis = 0.8;
} else if (credits > 0) {
dis = 0.9;
}
// 菜单程序
while (true) {
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("----------------------");
System.out.println("请输入操作编号:");
int opr2 = sc.nextInt();
if (opr2 == 1) {
System.out.println("1\t" + name1 + "\t" + price1);
System.out.println("2\t" + name2 + "\t" + price2);
System.out.println("3\t" + name3 + "\t" + price3);
} else if (opr2 == 2) {
// 购买
// 总计金额
double sum = 0;
String goOn = "";
do {
System.out.println("请输入商品编号:");
int pNo = sc.nextInt();
System.out.println("请输入商品数量:");
int num = sc.nextInt();
// 判断编号
if (pNo == 1) {
System.out.println(name1 + "\t" + price1 + "\t" + price1 * num);
sum += price1 * num;
} else if (pNo == 2) {
sum += price2 * num;
System.out.println(name2 + "\t" + price2 + "\t" + price2 * num);
} else if (pNo == 3) {
sum += price3 * num;
System.out.println(name3 + "\t" + price3 + "\t" + price3 * num);
} else {
System.out.println("暂无此商品");
}
// 是否继续购买
System.out.println("是否继续?y/n");
goOn = sc.next();
} while (goOn.equals("y"));
// 结束购买
System.out.println("您的折扣:" + dis);
System.out.println("折后价:¥" + (sum *= dis));
// 支付
// 支付
System.out.print("实际支付:");
double money = sc.nextDouble();
while (money < sum) {
System.out.print("请继续支付¥" + (sum - money));
money += sc.nextDouble();
}
System.out.println("找零:" + (money - sum));
} else if (opr2 == 3) {
System.out.println("折扣信息:" + dis);
} else if (opr2 == 4) {
System.out.println("请输入原密码");
String old = sc.next();
if (old.equals(pass)) {
System.out.println("请输入新密码");
String newPass = sc.next();
if (old.equals(newPass)) {
System.out.println("新密码不能和原密码相同");
} else {
pass = newPass;
System.out.println("修改成功");
// 退出当前二级菜单
break;
}
} else {
System.out.println("修改失败");
}
} else if (opr2 == 5) {
System.out.println("正在注销.....");
break;
} else {
System.out.println("非法操作,功能尚未开启");
}
}
} else {
System.out.println("密码错误");
}
} else {
System.out.println("账户不存在");
}
} else if (opr1 == 2) {
// 退出虚拟机
System.exit(0);
}
}
}
}
练习: 循环不停的接收成绩,直到接收0分,停止,计算总分和平均分
思路1 : 循环条件判断是否是0分
思路2: 接收,判断是否是0分,退出死循环
package demo;
import java.util.Scanner;
public class LianXi1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int count = 0;
double sum = 0;
while (true) {
System.out.println("请输入成绩");
int score = sc.nextInt();
if (score == 0) {
break;
} else {
sum += score;
count++;
}
}
System.out.println("总分" + sum);
System.out.println("平均分" + sum / count);
//思路2
// System.out.println("请输入学生"+ (++count) +" 成绩");
// int score = sc.nextInt();
// while(score != 0) {
// sum += score;
// //count ++;
// System.out.println("请输入学生"+ (++count) +" 成绩");
// //迭代
// score = sc.nextInt();
// }
// System.out.println("sum=" + sum);
// System.out.println("avg=" + sum / (count - 1));
}
}
2.5.2.3 do-while循环语法规则:
初始值;
do{
循环体;
迭代
}while(循环条件);
注意:
1.do-while比其他循环至少多执行1次
2.在do{}中定义的变量是无法在循环中使用,因此提升变量范围
2.5.3 三种循环对比
循环类型 | 特点 | 执行次数 |
---|---|---|
for | 语法清晰,简单,用于循环次数已知且固定,首选 | 0次或n次 |
while | 循环次数未知,根据外部条件决定,先判断条件执行 | 0次或n次 |
do-while | 循环次数未知,根据外部条件决定,先执行后判断条件 | 1次或n次 |
2.5.4 循环的退出
关键字 | 实现 |
---|---|
continue | 将当前循环略过,不执行循环体,继续下一个循环 |
break | 跳出当前循环(只能一层) |
continue 标签 | 略过循环 |
break 标签 | 跳出到标签指定循环外侧 |
return | 跳出到方法的外侧 |
System.exit(0); | 退出虚拟机 |
练习:小老虎吃包子,第三个包子有虫子(跳过)
package demo;
import java.util.Arrays;
/**
* 小老虎吃包子,第三个包子有虫子(跳过)
*continue;
*/
public class Lx {
public static void main(String[] args) {
for (int i = 1; i <= 5; i++) {
if (i == 3) {
continue;
}
System.out.println("小老虎在吃第" + i + "个包子");
}
}
}
练习:小老虎吃包子,吃完第三个就饱了,(不吃了)
package demo;
import java.util.Arrays;
/**
* 小老虎吃包子,吃完第三个就饱了,不吃了。
*/
public class Lx {
public static void main(String[] args) {
for (int i = 1; i <= 5; i++) {
// 先吃
System.out.println("小老虎在吃第" + i + "个包子");
// 吃完了第三个,满足条件,退出循环
if (i == 3) {
break;
}
}
}
}
标签
public class TestBreak {
public static void main(String[] args) {
//标签加在循环的上方
nao:
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
if(i == 2){
break nao;
//return;
}
System.out.println(i + "," + j);
}
}
System.out.println("这里....");
}
}
// 1 1 1 2 1 3 这里
10.25作业
作业1:从键盘上输入一个整数,判断是几位数
package com.qf.homework;
import java.util.Scanner;
/**
* 1. 从键盘上输入一个整数,判断是几位数
*/
public class Work1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个整数");
int a = sc.nextInt();
int temp = a;
int count = 0;
while (a > 0) {
count++;
a = a / 10;
}
System.out.println("您输入的数" + temp + "是" + count + "位数");
}
}
作业2:生成两个10-20之间的随机数,如果两个数不相等,再重新生成,直到两个数相等,且打印一共生成几次
package com.qf.homework;
import java.util.Random;
/**
* 2.生成两个10-20之间的随机数,
* 如果两个数不相等, 再重新生成,
* 直到两个数相等, 且打印一共生成几次
*/
public class Work2 {
public static void main(String[] args) {
// Random random = new Random();
// int count = 0;
// while (true) {
// int num1 = random.nextInt(11)+10;
// int num2 = random.nextInt(11)+10;
// if(num1 == num2) {
// System.out.println(num1 + "等于" + num2);
// break;
// }else {
// System.out.println("重新生成");
// count++;
// }
// }
// System.out.println("一共生成" + count + "次");
// 写法2
int count = 0;
while (true) {
int a = (int) ((20 - 10 + 1) * Math.random() + 10);
int b = (int) ((20 - 10 + 1) * Math.random() + 10);
if (a == b) {
System.out.println(a + "等于" + b);
break;
} else {
System.out.println(a + "," + b);
count++;
}
}
System.out.println("一共生成了" + count + "次");
}
}
作业3:
某城市出租车计费问题:
1.每日06:00-21:00,起步价6元,当日22:00-次日05:00,起步价7元。
2.起步价包含2公里,超出部分按照每公里1.5元收费。
3.每次乘车加收1元的燃油附加税。
输入打车的时间和距离(公里),计算本次打车的费用。
循环累加该车的费用,当输入打车距离为0 该车停止计费,统计金额
package com.qf.homework;
import java.util.Scanner;
public class Work3 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int start = 7;
double sum = 0;
while (true) {
System.out.println("请选择打车时间:1-(6:00-21:00) 2-(其余时间) ");
int opr = sc.nextInt();
System.out.println("请输入公里数");
double k = sc.nextDouble();
if (k == 0) {
break;
}
if (opr != 1) {
start = 8;
}
// 2公里
if (k <= 2) {
sum += start;
} else {
sum += start + (k - 2) * 1.5;
}
}
System.out.println("sum=" + sum);
}
}
作业4:
a
bb
ccc
dddd
eeeee
package com.qf.homework;
/**
* a
* bb
* ccc
* dddd
* eeeee
*
*/
public class Work4 {
public static void main(String[] args) {
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= i; j++) {
char c = (char)(i + 96);
// if (i == 1) {
// System.out.print("a");
// } else if (i == 2) {
// System.out.print("b");
// } else if (i == 3) {
// System.out.print("c");
// } else if (i == 4) {
// System.out.print("d");
// } else if (i == 5) {
// System.out.print("e");
// }
System.out.print(c);
}
System.out.println();
}
}
}
作业5:猜数游戏:
随机数生成 50-100的数字,控制台接收猜数数字,当大了或小了提示(区间),一共有五次机会
package com.qf.homework;
import java.util.Random;
import java.util.Scanner;
/**
* 5.猜数游戏: 随机数生成 50-100的数字,
* 控制台接收猜数数字,当大了或小了提示(区间),
* 一共有五次机会
*/
public class Work5 {
public static void main(String[] args) {
int num = (int) ((51) * Math.random() + 50);
Scanner sc = new Scanner(System.in);
int count = 0;
int a = 50, b = 100;
while (true) {
if (count == 5) {
System.out.println("次数已用完,结束");
System.out.println("本轮中奖数字" + num);
System.out.println("继续努力");
break;
}
count++;
System.out.println("请输入一个数字" + a + "~" + b + ":");
int op = sc.nextInt();
if (num == op) {
System.out.println("恭喜你,中奖");
break;
} else if (num < op) {
System.out.println("猜大了,还剩" + (5 - count) + "次机会");
b = op;
} else {
System.out.println("猜小了,还剩" + (5 - count) + "次机会");
a = op;
}
}
}
}
2.6 数组
·引用数据类型之一。
2.6.1 什么是数组
能够存储相同数据类型的一组数据,理解为数据集。
2.6.2 数组的作用
1. 方便批量数据存储
2. 方便一组数据批量管理
2.6.2 数组的特点(基本和引用类型区别)
1.数组存储于内存中 "堆",基本数据类型存储于栈
//变量
int a = 10,b = 30;
a = 20;
//数组
int [] arr = new int [5];
2.连续的存储空间,有下标,从0开始
3.堆中内存的回收,看JVM,栈中变量回收看{}
4.数组中每个值叫做数组的元素,数组有大小,数组名.length
2.6.4 数组的声明和创建
// 声明
数据类型 [] 数组名; // 推荐
数据类型 数组名 [];
注意
数组的数据类型:基本+引用(类/接口/枚举)
数组名的命名规范同变量名:(字母 数字 _ $ 不能是关键字,不能以数字开头),小写或驼峰
2.6.5 数组的创建语法格式(三种)
// 2.数组创建(背下来)
--1 第一种(元素个数,值后续动态赋给)// 下标范围 0~a.length-1
--2 第二种(元素已知)
数据类型 [] 数组名 = [元素1,元素2,元素3...];// 声明和创建不能分开写
--3 第三种
数组名 = new 数据类型 [] {元素1,元素2...}// 前两种结合
总结
数组经过创建后,有默认值,int:所有元素默认值0;
数组类型 | 默认值 |
---|---|
int | 0 |
double | 0.0 |
char | \u0000 |
boolean | false |
引用类型(String) | null(空) |
double [] d = new double [5];
System.out.println(d);//打印地址
System.out.println(d.length)//打印数组长度
//赋值
数组名 [下标] = 值;
// d[0] = 1.0;
// d[1] = 2.0;
// d[2] = 3.0;
// d[3] = 4.0;
// d[4] = 5.0;
//循环动态赋值
for (int i = 0; i < d.length; i++) {
d[i] = 1.0 + i;
}
//动态输出
for (int i = 0; i < d.length; i++) {
System.out.println(d[i]);
}
练习:控制台接收4个元素赋值给数组,动态打印
public class TestArray4 {
public static void main(String[] args) {
int [] a = new int[4];
Scanner sc = new Scanner(System.in);
for (int i = 0; i < a.length; i++) {
System.out.println("请输入第" + (i + 1) + "个值");
a[i] = sc.nextInt();
}
//打印值
// for (int i = 0; i < a.length; i++) {
// System.out.print(a[i] + "\t");
// }
//数组的输出
System.out.println(Arrays.toString(a));
}
}
10.26作业
作业1:评委打分
package com.qf.homework;
import java.util.Scanner;
public class Work1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 定义五个元素的数组
int[] score = new int[5];
int max = 0, min = 999;
double sum = 0;
// 标记
boolean boo = true;
// 动态赋值
for (int i = 0; i < score.length; i++) {
System.out.println("请第" + (i + 1) + "个评委打分");
score[i] = sc.nextInt();
// 分数为0,淘汰
if (score[i] == 0) {
System.out.println("你被淘汰了");
boo = false;
// break;
continue;
}
sum += score[i];
if (score[i] > max) {
max = score[i];
}
if (score[i] < min) {
min = score[i];
}
}
System.out.println("去掉最高分" + max);
System.out.println("去掉最低分" + min);
if (boo) {
System.out.println("参赛成绩" + (sum - max - min) / (score.length - 2));
} else {
System.out.println("参赛成绩0.0");
}
}
}
作业2:
package com.qf.homework;
import java.util.Arrays;
/**
* 2. 把一个数组的元素逆序交换,
* int[] a = { 5, 11, 55, 24, 36, 47, 59, 66 };
* 交换元素后 int[] a ={ 66 ,59 ,47 ,36 ,24,55 ,11 ,5 };
*
*/
public class Work2 {
public static void main(String[] args) {
int[] a = { 5, 11, 55, 24, 36, 47, 59, 66 };
System.out.println("逆置前");
System.out.println(Arrays.toString(a));
// for (int i = a.length - 1; i >= 0; i--) {
// System.out.print(a[i] + "\t");
// }
// 交换次数 8个数交换4次得到(a.length / 2)
// 0 换 7
// 1 换 6
// 2 换 5
// 3 换 4
for (int i = 0; i < a.length / 2; i++) {
// 交换
int temp = a[i];
a[i] = a[a.length - 1 - i];
a[a.length - 1 - i] = temp;
}
System.out.println("逆置后");
System.out.println(Arrays.toString(a));
}
}
作业3:彩票 33选7 双色球
package com.qf.homework;
import java.util.Arrays;
import java.util.Scanner;
public class Work3 {
public static void main(String[] args) {
// 机选
int blue = (int) (16 * Math.random() + 1);
int[] reds = new int[6];
for (int i = 0; i < reds.length; i++) {
// 当前生成的数字
reds[i] = (int) (33 * Math.random() + 1);
/**
* 去重
*/
// 和前面生成的每个人比较
for (int j = 0; j < i; j++) {
if (reds[i] == reds[j]) {
i--;
break;
}
}
}
Scanner sc = new Scanner(System.in);
int pBlue = 0;
int[] pReds = new int[6];
do {
System.out.println("欢迎进入双色球彩票系统 票价2元");
System.out.println("请输入蓝色球(1-16)");
pBlue = sc.nextInt();
System.out.println("请输入六个红色球(1-33)");
for (int i = 0; i < pReds.length; i++) {
pReds[i] = sc.nextInt();
}
System.out.println("是否确定? y/n");
} while (sc.next().equals("n"));
// 确定
System.out.println("您选择号码如下:");
System.out.println("蓝色球:" + pBlue);
System.out.println("红色球:" + Arrays.toString(pReds));
// 看中奖情况
boolean f = false;
if (blue == pBlue) {
f = true;
}
// 红球
int count = 0;
for (int i = 0; i < pReds.length; i++) {
for (int j = 0; j < reds.length; j++) {
if (pReds[i] == reds[j]) {
count++;
}
}
}
// 判断
if (f && count == 6) {
System.out.println("3000万");
} else if (!f && count == 5) {
System.out.println("500万");
} else if (f && count == 3) {
System.out.println("50万");
} else if (f && count == 2) {
System.out.println("20万");
} else if (f && count == 1 || !f && count == 2) {
System.out.println("5元");
} else {
System.out.println("感谢您支持彩票业务");
}
System.out.println("本次中奖号码");
System.out.println("Blue:" + blue);
System.out.println("Reds:" + Arrays.toString(reds));
}
}
2.6.5 数组的应用
经典问题1: 求和和平均值
控制台接收五个学生成绩,存储到数组中,获取五个学生的总分和平均分
public class ArrayAppli1 {
public static void main(String[] args) {
double [] score = new double[5];
Scanner sc = new Scanner(System.in);
System.out.println("请输入五个学生成绩");
double sum = 0;
for (int i = 0; i < score.length; i++) {
score[i] = sc.nextDouble();
sum += score[i];
}
System.out.println("总分:" + sum);
System.out.println("平均值:" + sum / score.length);
}
}
经典问题2: 最大值 最小值
控制台接收五个学生成绩,存储到数组中,获取最高分(第几个),最低分(第几个)
public class ArrayAppli2 {
public static void main(String[] args) {
double [] score = new double[5];
Scanner sc = new Scanner(System.in);
System.out.println("请输入五个学生成绩");
double max = 0,min = Double.MAX_VALUE;
int maxIndex = -1, minIndex = -1;
for (int i = 0; i < score.length; i++) {
score[i] = sc.nextDouble();
if(score[i] > max) {
max = score[i];
maxIndex = i;
}
if(score[i] < min) {
min = score[i];
minIndex = i;
}
}
System.out.println("最高分:" + max + "是第" + (maxIndex + 1) + "个人");
System.out.println("最低分:" + min + "是第" + (minIndex + 1) + "个人");
}
}
经典问题3: 计数
定义一个数组,存储(1,2,3,4,5,6,7,8,9,10)
遍历数组得到每一个元素,统计数组里面一共有多少个能被3整除的数字
package demo;
import java.util.Random;
import java.util.Scanner;
public class Lx {
public static void main(String[] args) {
int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int count = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] % 3 == 0) {
System.out.println(arr[i]);
count++;
}
}
System.out.println("数组中能被3整除的数字有" + count + "个");
}
}
录入五个成绩,统计优秀和良好的人数
public class ArrayAppli3 {
public static void main(String[] args) {
double [] score = new double[5];
Scanner sc = new Scanner(System.in);
System.out.println("请输入五个学生成绩");
int c1 = 0, c2 = 0;
for (int i = 0; i < score.length; i++) {
score[i] = sc.nextDouble();
if(score[i] >= 90 && score[i] <= 100) {
c1 ++ ;
}else if(score[i] >= 80) {
c2 ++;
}
}
System.out.println("优秀人数:" + c1);
System.out.println("良好人数:" + c2);
}
}
练习:生成10个1~100之间的随机数存入数组,求出所有的数据和,求出所有数据的平均值,统计有多少个数据比平均值小
package demo;
import java.util.Random;
import java.util.Scanner;
public class Lx {
public static void main(String[] args) {
int[] arr = new int[10];
for (int i = 0; i < arr.length; i++) {
int sjs = (int) ((100 - 1 + 1) * Math.random() + 1);
arr[i] = sjs;
}
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
System.out.println("所有数据的和" + sum);
int avg = sum / arr.length;
System.out.println("平均数据" + avg);
int count = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] < avg) {
count++;
}
}
for (int i : arr) {
System.out.print(i + " ");
}
System.out.println();
System.out.println("有" + count + "个数据比平均值小");
}
}
练习:定义一个数组,存入(1,2,3,4,5)交换首位索引对应的元素。
package demo;
import java.util.Random;
import java.util.Scanner;
public class Lx {
public static void main(String[] args) {
// 交换前:1 2 3 4 5
// 交换后:5 4 3 2 1
int[] arr = { 1, 2, 3, 4, 5 };
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
for (int i = 0, j = arr.length - 1; i < j; i++, j--) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
for (int i : arr) {
System.out.print(i + " ");
}
}
}
练习:定义一个数组,存入1~5.要求打乱数组中所有数据的顺序。
package demo;
import java.util.Random;
import java.util.Scanner;
public class Lx {
public static void main(String[] args) {
int[] arr = { 1, 2, 3, 4, 5 };
Random r = new Random();
for (int i = 0; i < arr.length; i++) {
int num = r.nextInt(arr.length);
int temp = arr[i];
arr[i] = arr[num];
arr[num] = temp;
}
for (int i : arr) {
System.out.print(i + " ");
}
}
}
int[] a = {12,56,34,0,15,7,0} ,去掉0的新数组
package demo;
import java.util.Arrays;
import java.util.Scanner;
/**
* int[] a = {12,56,34,0,15,7,0} ,去掉0的新数组
*/
public class LianXi1 {
public static void main(String[] args) {
int[] a = { 12, 56, 34, 0, 15, 7, 0 };
//统计0个数
int count = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] == 0) {
count++;
}
}
//新数组长度
int[] b = new int[a.length - count];
//遍历a数组,将a数组的元素存储到b中
int index = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] != 0) {
b[index++] = a[i];
}
}
System.out.println(Arrays.toString(b));
}
}
经典问题4: 数组遍历
打印数组的每个元素:数组的遍历。
1.正常for循环访问下标
int[] a = new int[] {12,45,34,89,12,6,7,8};
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + "\t");
}
2.jdk5+ foreach (增强for)
for(数据类型 迭代变量 : 数组名){
打印迭代变量;
}
3.API中Arrays输出,以字符串形式打印所有元素
System.out.println(Arrays.toString(数组名));
练习:定义一个数组,存储(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)遍历数组得到每一个元素,如果是奇数,则将当前数字1扩大两倍,如果是偶数,则将当前数字变成二分之一
package demo;
import java.util.Random;
import java.util.Scanner;
public class Lx {
public static void main(String[] args) {
int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for (int i = 0; i < arr.length; i++) {
if (arr[i] % 2 != 0) {
arr[i] *= 2;
} else if (arr[i] % 2 == 0) {
arr[i] /= 2;
}
}
//遍历数组
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
经典问题5: 排序算法(数字)
将元素从小到大(升序),从大到小(降序)排序。
经典排序算法: 冒泡排序,选择排序,插入排序,希尔排序,归并排序,快速排序,堆排序…
1.冒泡排序(下沉法)
一组元素,将每两个挨着的进行两两比较交换,将大的下沉,小的上浮,最大的沉到最下面,完成一次冒泡,剩余的数字按照理论继续。N个数冒泡 :
冒泡N-1次。
代码实现:
public class ArrayAppli7 {
public static void main(String[] args) {
int[] a = new int[] {12,45,34,89,12,6,7,8};
//冒泡次数
for (int i = 1; i < a.length; i++) {
//比较交换
// i= 1 j=0 j=1 j=2
for (int j = 0; j < a.length - i; j++) {
//比较
if(a[j] > a[j + 1]) {
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
for (int i : a) {
System.out.println(i);
}
}
}
2.选择排序
一组元素,将每个下标位置上的元素和其他位置相比较,做交换,直到确认这个位置是最小的(最大的),完成一次交换,剩下的位置再按照理论进行…
public class TestArray1 {
public static void main(String[] args) {
int [] a = {423,113,25,13,45,23,88,4};
for (int i = 0; i < a.length - 1; i++) {
for (int j = i + 1; j < a.length; j++) {
if(a[i] > a[j]) {
int t = a[i];
a[i] = a[j];
a[j] = t;
}
}
}
//foreach
for (int i : a) {
System.out.println(i);
}
}
}
3.使用JAVA中提供排序方法
//JAVA中定义好的类,java.util.Arrays;
Arrays.sort(数组名); // 升序
经典问题6: 查找
1.线性查找
将目标元素和数组中每个元素依次比较,如果找到,检索成功,当全部检索完毕,没有,不存在该元素
public class TestArray4 {
public static void main(String[] args) {
int[] a = {12,56,44,87,4,76,80};
Scanner sc = new Scanner(System.in);
System.out.println("请输入检索的目标元素");
int target = sc.nextInt();
//标签
//boolean f = true;
int count = 0;
for (int i = 0; i < a.length; i++) {
if(a[i] == target) {
System.out.println("找到了" + target + "元素");
System.out.println("第" + (i + 1) + "个元素");
//f = false;
count ++;
break;
}
}
if(count == 0) {
System.out.println("没有该元素");
}
}
}
2.折半查找(二分查找法)
前提要求: 排序后,,每次取出中间位置上的元素和目标比较,正好相等,找到该元素,当目标元素大于中间位置,范围缩小到左半部分,左半部分的中间位置元素和目标继续比较…, 当目标元素大于中间位置,范围锁定在中间位置的右半部分,
public class TestArray5 {
public static void main(String[] args) {
// int[] a = {12,56,44,87,4,76,80};
int[] a = { 12, 35, 65, 78, 84, 92, 110 };
Scanner sc = new Scanner(System.in);
System.out.println("请输入检索的目标元素");
int target = sc.nextInt();
// 排序
Arrays.sort(a);
int s = 0, e = a.length - 1;
boolean f = true;
while (s <= e) {
int m = (s + e) / 2;
if (a[m] == target) {
System.out.println("找到");
f = false;
break;
} else if (a[m] < target) {
s = m ;
} else {
e = m ;
}
}
if (f) {
System.out.println("没有该元素");
}
}
}
3.JAVA API
Arrays.sort(a);
Arrays.binarySearch(数组名,目标元素); // 排序后查找下标 >=0 包含
经典问题7: 数组合并
将两个数组合并为一个数组。
public class TestCover {
public static void main(String[] args) {
int [] a = {12,45,67,71};//4
int [] b = {34,56,88,4,93};// 5
//将两个数组合并为一个
int [] c = new int[a.length + b.length];
for (int i = 0; i < a.length; i++) {
c[i] = a[i];
}
for (int i = 0; i < b.length; i++) {
//
c[i + a.length] = b[i];
}
System.out.println(Arrays.toString(c));
}
}
// 写法2
public static void main(String[] args) {
int [] a = {12,45,67,71};//4
int [] b = {34,56,88,4,93};// 5
//将两个数组合并为一个
int [] c = new int [a.length+b.length];
for (int i = 0; i < c.length; i++) {
if(i < a.length){
c[i] = a[i];
}else{
c[i] = b[i-a.length];
}
}
System.out.println(Arrays.toString(c));
}
// API实现 原数组 起始位置 目标数组 起始位置 复制长度
System.arraycopy(a, 0, c, 0, a.length);
System.arraycopy(b, 0, c, a.length, b.length);
System.out.println(Arrays.toString(c));
10.27 作业
作业1:控制台接收一个含有8个元素的数组,获取出现次数最多的元素以及个数
package com.qf.homework;
import java.util.Scanner;
/**
* 控制台接收一个含有8个元素的数组,获取出现次数最多的元素以及个数
*/
public class Work1 {
public static void main(String[] args) {
int[] b = new int[8];
Scanner sc = new Scanner(System.in);
int max = 0, index = 0;
// 获得出现次数最多的元素以及对应的次数
for (int i = 0; i < b.length; i++) {// 01234567
System.out.println("请输入元素");
b[i] = sc.nextInt();
int count = 0;
for (int j = 0; j < b.length; j++) {// 1234567
if (b[i] == b[j]) {
count++;
}
if (max < count) {
max = count;
index = i;
}
}
}
System.out.println("出现次数最高的元素是" + b[index] + ",出现了" + max + "次");
}
}
作业1拓展:
package com.qf.homework;
import java.util.Scanner;
/**
* 控制台接收一个含有8个元素的数组,获取出现次数最多的元素以及个数
*
* @author
*
*/
public class Work1_2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[] a = new int[8];
int index = 0, max = 0;
for (int i = 0; i < a.length; i++) {
System.out.println("请输入第" + (i + 1) + "个元素");
a[i] = sc.nextInt();
int count = 1;
for (int j = 0; j < i; j++) {
if (a[i] == a[j]) {
count++;
}
}
if (max < count) {
max = count;
index = a[i];
}
}
System.out.println("出现次数最多的是" + index);
System.out.println("出现了" + max + "次");
}
}
经典问题8: 去重和重复
重复:
package demo;
import java.util.Arrays;
public class Lx {
public static void main(String[] args) {
// 统计两个数组中元素重复个数
int[] a = { 12, 45, 67, 89, 23, 6, 4 };
int[] b = { 5, 89, 12, 90, 55 };
int count = 0;
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < b.length; j++) {
if (a[i] == b[j]) {
count++;
}
}
}
System.out.println(count);
}
}
重复2: 统计数组中每个元素出现的次数
//思路1:
public class TestRepeat2 {
public static void main(String[] args) {
// 统计两个数组中元素重复个数
int[] a = {45,45,45,12,45,67,89,23,6,4,12,34,23,12,12};
// a[0] = 12
int max = 0 ,index = -1;
for (int i = 0; i < a.length; i++) {
int count = 1;
for (int j = i + 1; j < a.length; j++) {
if(a[i] == a[j]) {
count ++;
}
}
if(max < count) {
max = count;
//index = i;
}
}
System.out.println(max);
//System.out.println("出现次数最多的是:" + a[index] + "次数:" + max);
}
}
//思路2:
public class TestRepeat3 {
public static void main(String[] args) {
int[] a = new int[6];
Scanner sc = new Scanner(System.in);
System.out.println("亲输入元素");
int max = 0, index = -1;
for (int i = 0; i < a.length; i++) {
a[i] = sc.nextInt();
int count = 1;
for (int j = 0; j < i; j++) {
if(a[i] == a[j]) {
count ++;
}
}
if(max < count) {
max = count;
index = i;
}
}
System.out.println("出现次数最多的是:" + a[index] + "次数:" + max);
}
}
去重:
1.生成无重复的数组元素
package demo;
import java.util.Arrays;
public class Lx {
public static void main(String[] args) {
int[] reds = new int[6];
for (int i = 0; i < reds.length; i++) {
// 当前生成的数字
reds[i] = (int) (33 * Math.random() + 1);
// 去重
// 和前面生成的每个人比较
for (int j = 0; j < i; j++) {
if (reds[i] == reds[j]) {
i--;
break;
}
}
}
for (int i : reds) {
System.out.print(i + " ");
}
}
}
2.数组去掉重复元素
package demo;
import java.util.Arrays;
public class Lx {
public static void main(String[] args) {
int[] a = { 45, 88, 23, 45, 45, 12, 78, 91, 12 };
int[] b = new int[a.length];
int index = 0;
for (int i = 0; i < a.length; i++) {
boolean flag = true;
for (int j = 0; j < i; j++) {
if (a[i] == a[j]) {
// 有重复
flag = true;
break;
}
}
// 没有重复
if (flag) {
b[index] = a[i];
index++;
}
}
int[] c = new int[index];
// 复制
System.arraycopy(b, 0, c, 0, index);
System.out.println(Arrays.toString(c));
}
}
2.6.6 数组的大小和传值
数组的大小:
数组的大小一经创建后,固定的,不允许更改大小。
int [] a = new int [4];
a = new int [5];
数组在传值(赋值),赋给的是地址引用。
//引用类型
int[] b = a;//传地址
b[1] = 88;
System.out.println(Arrays.toString(a));
//int i = 10;
//int j = i;//传值
//i ++;
//System.out.println(i + "," + j);//11 10
2.6.7 二维数组和多维数组
二维数组(了解)
数组的元素不是直接的数值,而是一个个数组。
声明:
数据类型 [][] 数组名 ;
数据类型 数组名 [][] ;
数据类型 [] 数组名 [] ;
创建:
数据类型 [][] 数组名 = {{1,2,3},{4,5},{6,7}};
数组名 = new 数据类型[二维数组大小][];
示例:
int [][] a = {{1,2},{3},{5,6}};
double d[][] = new double[3][];
String []s[];
遍历二维数组:
int [][] a = {{1,2,5},{3,4,2},{5,6,8}};
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
System.out.print(a[i][j] + "\t");
}
System.out.println();
}
练习:声明3*3二维数组(三个一维数组,三个值),对角线的和
int sum = 0;
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
System.out.print(a[i][j] + "\t");
if(i == j || i + j == a.length - 1) {
sum += a[i][j];
}
}
System.out.println();
}
第三章 面向对象编程
企业开发流程:
1.需求分析
2.设计
3.开发
4.测试
5.运维
OOA 面向对象分析
OOD 面向对象设计
OOP 面向对象编程
面向对象的设计思想
3.1.1 面向对象和面向过程理解
1.面向过程 将系统需求按照事情的发现顺序拆解问题,按照事务的发展过程。 (C语言)
2.面向对象 将系统需求拆解成一类一类事物,按类别划分,解决问题。 (JAVA,C++ ,C#)
超市系统:内部系统
面向过程: 顾客小红 > 购买 (挑选商品)> 结算 > 支付
面向对象: 顾客类 / 商品类 / 订单类 / 收银 / 供应商
五子棋游戏 :
面向对象: 黑方 白方 游戏系统
3.1.2 面向对象和面向过程核心
面向过程: 核心是 函数
面向对象: 核心是 对象(类)
3.1.3 面向对象的好处
1. 更接近现实生活,清晰分析系统
2. 避免代码的冗余
3. 同一个系统,采用不同的分析方式
3.2 类和对象
类: 一类事物的统称。
对象: 实际存在的个体。
类是对象的抽象,归总出的概念,不是实际的存在。 不占内存,
对象是具体化,实际真正的个体,对象是类的具体的实例。 占内存。
举例 : 文具和文具盒 ; 海王和康吉 ; 水果和苹果 ; 游戏和LOL ; 学生和齐威
分析问题:
对象 > 类 方便一类事物的描述和使用
解决问题:
类 > 对象
类的声明:
控制权限 class 类名{
属性;
方法;
}
注意:
权限: 类的使用范围,public 公开权限,什么都不加(友好),一个源文件只有一个加public(和源文件名相同)
class 关键字 声明类
类名:
1.字母 数字 _ $ 构成,数字不能开头
2.不能是关键字
3.首字母大写
4.有含义
类的构成:(重点)
属性 : 一类事物的特点,特征,参数,用于描述一类事物的静态信息,如 衣服颜色,学生姓名,身高
方法 : 一类事物的行为,动作,能力,用于描述一类事物动态信息, 吃法,打球,睡觉,学习...
获取嫌疑人: 目击者描述
- 男性 175 戴眼镜 微胖 黑色衣服 牛仔裤 白色球鞋 (属性)
- 嘴里嚼口香糖 跑步 打电话 (方法),能打架
骑手类 :
护具 新摩托车
骑行
学生类:
学号,姓名,年龄,班级,身份证,性别
学习,睡觉,写作业,打游戏,吃饭
属性的声明:
控制权限 数据类型 属性名 [=初始值] ;
注意:
数据类型 : 基本/引用
属性名 : 同变量名 xXXX xxx
初始值: 有默认值 int 0 double 0.0 boolean false char \u0000 引用 null
public class Student {
/**
* 属性
*/
public int sNo ; // 学号
public String sName ; //姓名
public char gender = '男' ;//性别
public double[] score ; //多个分数
public double height;//身高
}
练习:
public class Customer {
/**
* 属性
*/
// 顾客编号
public int cNo;
// 顾客姓名
public String cName;
// 账户余额
public double balance;
// 是否是vip
public boolean isVip ;
}
总结:
属性相当于一类事物的数据参数,定义一些变量和常量。
方法的声明(重点)
控制权限 [修饰符] 返回类型 方法名(参数类型 参数变量,参数类型 参数变量){
方法体;
[return 值];
}
public static void main(String[] args) {
}
注意:
-
控制权限 public
-
返回类型
无返回值类型:执行结束后,不需要返回结果 void
有返回值类型:声明方法返回类型: int / double / String /数组
一旦定义了返回类型,方法体的最后有 return xx ; 只能一个返回结果;
-
方法名同变量名
-
参数可以有,没有参数
有参数: 方法需要接收外部数据参数,再处理
方法声明的参数 : 形参(变量),多个参数使用,隔开, 每个都指名类型
方法调用的参数 : 实参 (值)
无参数: 方法不需要接收参数
/**
* 吃饭: 无参数,无返回
*/
public void eat() {
System.out.println(sName + "正在吃饭");
}
/**
* 学习 : 返回每天学习时间 无参数,有返回
*/
public double study() {
System.out.println(sName + "在库库学习");
//方法的最后返回结果(退出方法并返回值)
return 8.5;
}
练习:
/**
* 返回顾客是否是vip
*/
public boolean getVip() {
return isVip;
}
/**
* 购买: 显示xxx正在购物
*
*/
public void buy() {
System.out.println(cName + "正在购物....");
}
案例:
/**
* 学生算术: 计算两个数和 有参,无返回
*/
public void calc(int a , int b) {
System.out.println(sName + "开动大脑计算...");
System.out.println(a + b);
}
/**
* 学生算术: 计算三个数,返回三个数 最大值 有参 有返回
*/
public int max(int a , int b ,int c) {
int max = a > b ? a : b;
max = max > c ? max : c;
return max;
}
练习:
/**
* 支付: 参数是需要支付的原价
* 返回的是顾客支付金额: 如果vip 8折 原价
*/
public double pay(double money) {
double pay = 0;
if(isVip) {
pay = money * 0.8;
}else {
pay = money;
}
//减掉,余额更新
balance -= pay;
return pay;
}
/**
* 根据积分,办理 vip
* 判断积分大小 5000以上 vip是
*
*/
public void setVip(int points) {
if(points >= 5000) {
isVip = true;
}else {
isVip = false;
}
}
综合练习:
// 管理员类
Admin
属性: 账号 密码 登录身份(int : 1 高级权限 2 普通权限)
方法:
登录 : 传入账户和密码 比较 void 打印登录情况
获取账户权限 : 有返回值,无参数
总结: 类的设计
类图:呈现类的设计
练习:
提示:随机数
public class Computer {
//属性
public int score;
public String name;
//方法
public String show() {
int a = (int)(3 * Math.random() + 1);
if(a == 1) {
return "石头";
}else if(a == 2) {
return "剪刀";
}else {
return "布";
}
}
}
3.3 创建对象
将抽象的类具体化到实际存在的个体。
对象创建的语法规则:
类名 对象名 = new 类名();
注意:
对象的创建写在类的外部
public class TestComputer {
public static void main(String[] args) {
//创建对象
Computer dell = new Computer();
//电脑出拳
dell.name = "戴尔886";
System.out.println(dell.show());
}
}
注意:
当使用类创建了对象,该对象具备本类事物的全部特性。
Admin wsj = new Admin();
内存信息:堆开辟对象,堆中存储属性,属性有默认值:
数据类型 | 默认值 |
---|---|
int | 0 |
double | 0.0 |
char | \u0000 |
boolean | false |
引用类型(String) | null(空) |
堆栈图:
测试类:
public class TestAdmin {
public static void main(String[] args) {
//创建一个管理员对象
Admin wsj = new Admin();
//十六进制打印地址
//System.out.println(wsj);
wsj.id = "GoodJun";
wsj.pass = "123456";
wsj.level = 2;
System.out.println(wsj.id); //GoodJun
System.out.println(wsj.pass); //123456
System.out.println(wsj.level);//2
//获取权限
System.out.println(wsj.getLevel());
}
}
属性的调用:
//赋值
对象名.属性 = 赋值;
//打印属性值
System.out.println(s.sName);
类中的属性是数组类型:
public class Student {
/**
* 属性
*/
public int sNo ; // 学号
public String sName ; //姓名
public char gender = '男' ;//性别
public double[] score ; //多个分数
public double height;//身高
}
测试:
public class TestStudent {
public static void main(String[] args) {
Student s = new Student();
s.sNo = 1001;
s.sName = "阿香";
s.gender = '女';
s.height = 180;
//创建数组
s.score = new double[] {100,90,66};
System.out.println(s.sName);
System.out.println(s.sNo);
System.out.println(s.gender);
System.out.println("分数如下:");
//遍历数组,获得分数
System.out.println(s.score);
System.out.println(s.score[0]);
// for (double i : s.score) {
// System.out.println(i);
// }
}
}
内存信息:
3.4 变量的分类
全局变量(属性)和局部变量(main)。
全局变量(属性) | 局部变量 | |
---|---|---|
声明位置 | 类里,方法外 | 方法内部,方法的参数变量 |
默认值 | 有 | 没有的 |
调用方式 | 对象.属性 | 直接用 |
权限问题 | 必须添加权限 | 没有权限 |
使用范围 | 整个类 | 语句块 |
生命周期 | 对象创建时,对象销毁 | { } |
内存 | 堆 | 栈 |
关键问题:
当全局变量和局部变量重名,局部变量将全局的覆盖。使用this.属性调取被覆盖的属性。
if(id.equals(this.id)) {
if(pass.equals(this.pass)) {
System.out.println("登录成功");
}else {
System.out.println("密码错误");
}
}else {
System.out.println("账户不存在");
}
3.5 方法的调用
语法规则:
对象名.方法名([实参1,实参2..]);
注意:
1.当方法声明的时候,定义了形参变量,方法调用的时候,必须给实参 形参是变量,实参是值。形参和实参的关系:赋值关系(个数,类型,顺序完全匹配)
形参 = 实参
2.方法调用的时候,到方法内执行,执行完,是否有返回值,返回值给调用位置
3.5.1 方法的几种调用方式
1.类外部调用
对象.方法();
package com.qf.oop;
/**
* 商家
* @author 86136
*
*
*/
public class Seller {
//名字
public String name;
//地址
public String address;
//电话
public String tel;
//主营类型
public String type;
//餐品
public String[] foods;
/**
* 上新
*/
public void news(String[] foods) {
this.foods = foods;
}
/**
* 回复评论
*/
public String reply(String words) {
System.out.println(words + "感谢您的评价");
return "统一回复: 好吃下次再来";
}
}
测试方法调用:
public class TestSeller {
public static void main(String[] args) {
Seller s = new Seller();
s.name = "小红旗";
s.type = "冷面臭豆腐";
s.address = "万达金街";
//上新
s.news(new String[] {"炸冷面","冷面臭豆腐","香肠","面筋"});
//获得餐品
for (int i = 0; i < s.foods.length; i++) {
System.out.print(s.foods[i] + "\t");
}
System.out.println();
//评价
Scanner sc = new Scanner(System.in);
System.out.println("请输入您的评价");
System.out.println(s.reply(sc.next()));
}
}
2.类内部调用
类里的a方法调用b方法
a(){
//直接调用
// this.b();
b();
}
b(){
}
package com.qf.oop;
/**
* 分数计算类
* @author 86136
*
*/
public class ScoreCalc {
public int java;
public int db;
public int c;
/**
* 计算总分
* @return
*/
public int sum() {
return java + db + c;
}
/**
* 计算平均分
*/
public double avg() {
return this.sum() / 3.0;
}
/**
* 显示打印平均分
*/
public void print() {
System.out.println(avg());
}
}
注意:
调用原则: 当a方法调用b方法,必须先执行b方法,b方法执行结束,回到a方法接着执行。
public class TestCall {
public void a() {
c();
System.out.println("a");
}
public void b() {
System.out.println("b");
}
public void c() {
b();
System.out.println("c");
}
public static void main(String[] args) {
new TestCall().a();
}
}
//b
//c
//a
public class TestCall2 {
public void a() {
c();
System.out.println("a");
}
public int b() {
System.out.println("b");
return 2;
}
public void c() {
System.out.println("2" + b());
System.out.println("c");
}
public static void main(String[] args) {
new TestCall2().a();
}
}
//b
//22
//c
//a
3.递归调用
方法自己调用自己的过程,叫递归调用,递归调用必须要有结束条件,否则就是死递归。
//设计方法: 传入一个数字n,获得n的阶乘
1! = 1
2! = 1! * 2
3! = 2! * 3
n! = (n - 1)! * n
public class TestCall3 {
/**
* 求阶乘 3
*/
public double getJc(int n) {
//结束
if(n == 1) {
return 1;
}
return n * getJc(n - 1);
}
public static void main(String[] args) {
double b = new TestCall3().getJc(3);
System.out.println(b);
}
}
3.5.2 方法的参数个数
1.无参数 public int add(){}
2.固定个数
public int add(int a,int b) {}
public int getJc(int n){}
3.不固定个数的方法
可变长参数(JDK5+)
控制权限 返回值 方法名 (参数类型 参数1 ,参数数据类型...参数名){
}
注意:
1.可变长参数必须放在参数列表的最后
2.可变长参数在方法中,视为数组
//不限制参数个数的方法
public void sum(int...a) {
int sum = 0;
for (int i = 0; i < a.length; i++) {
sum += a[i];
}
System.out.println(sum);
}
重载方法: 相同方法名,根据参数不同(参数个数,类型,顺序),共存于一个类中。
public class TestParam3 {
//方法的重载,方法名相同,参数不同
public void sum(int a,int b) {
}
// public void sum(int m,int n) {
//
// }
public void sum(int a,int b,int c) {
}
public void sum(double c,int d) {
}
public void sum(int c,double d) {
}
public static void main(String[] args) {
new TestParam3().sum(1, 2,4);
}
}
3.5.3 方法的参数传递问题
实参向形参传值:(赋值)
基本数据类型: 传递值
引用数据类型: 传递地址
public class Game {
public void testGame(int a,Player p) {
a ++;
p.name = "帅气君君";
}
public static void main(String[] args) {
Game g = new Game();
Player p = new Player();
p.name = "天仙娃娃";
int a = 10;
g.testGame(a,p);
System.out.println(a); //10
System.out.println(p.name);//帅气君君
}
}
public class Test3 {
//交换方法
public void change(int x,int y) {
int t = x;
x = y;
y = t;
System.out.println(x + "," + y);// 2 1
}
public static void main(String[] args) {
int x = 1 ,y = 2;
new Test3().change(x, y);
System.out.println(x + "," + y);// 1 2
}
}
3.6 对象数组
当出现多个对象,使用对象数组来维护多个相同类型的对象。
对象数组的语法:
类[] 数组名 = new 类[数组大小];
案例: 创建多个玩家
Player[] p = new Player[3];
Player [] p = new Player[3];
Scanner sc = new Scanner(System.in);
for (int i = 0; i < p.length; i++) {
//循环创建对象,给数组赋值
p[i] = new Player();
System.out.println("请输入玩家名");
p[i].name = sc.next();
System.out.println("请输入等级");
p[i].level = sc.nextInt();
}
学生类
public class Student {
public int no;
public String name;
public double score;
public String toString() {
return "Student [no=" + no + ", name=" + name + ", score=" + score + "]";
}
}
学生系统管理类
/**
* 学生系统类(维护学生)
* @author 86136
*
*/
public class StudentSys {
//学生类型的数组
public Student[] stus = new Student[3];
Scanner sc = new Scanner(System.in);
/**
* 初始化学生
*/
public void init() {
//动态初始化学生
for (int i = 0; i < stus.length; i++) {
stus[i] = new Student();
System.out.println("请输入第"+ (i + 1)+ " 个学生的学号");
stus[i].no = sc.nextInt();
System.out.println("请输入第"+ (i + 1)+ " 个学生的姓名");
stus[i].name = sc.next();
System.out.println("请输入第"+ (i + 1)+ " 个学生的成绩");
stus[i].score = sc.nextDouble();
}
}
/**
* 菜单程序
*/
public void menu() {
init();
//死循环
while (true) {
System.out.println("----------------------");
System.out.println("1-查找学生信息");
System.out.println("2-获取最高分学生信息");
System.out.println("3-退出系统");
System.out.println("----------------------");
System.out.println("请输入操作编号:");
int opr = sc.nextInt();
if(opr == 1) {
System.out.println("请输入要查找学生学号:");
int index = find(sc.nextInt());
if(index != -1) {
System.out.println("该学生信息如下:");
System.out.println(stus[index]);
}else {
System.out.println("学生不存在");
}
}else if(opr == 2) {
System.out.println("最高分数学生信息:" + getMax());
}else if(opr == 3) {
break;
}else {
System.out.println("非法操作");
}
}
}
/**
* 查找学生信息
*/
public int find(int no) {
int index = -1;
for (int i = 0; i < stus.length; i++) {
if(no == stus[i].no) {
index = i;
break;
}
}
return index;
}
/**
* 获得最高分学生
*/
public Student getMax() {
double max = 0;
int index = -1;
for (int i = 0; i < stus.length; i++) {
if(max < stus[i].score) {
max = stus[i].score;
index = i;
}
}
return stus[index];
}
//测试类
public static void main(String[] args) {
StudentSys s = new StudentSys();
s.menu();
}
}
3.7 构造方法
3.7.1 什么是构造方法
又叫做”构造器“,构造方法是类中一种特殊的方法,用于创建对象的时候提供属性默认值的。如:
年龄创建对象的时候就是1,会员卡初始200元,出生的时候性别。
3.7.2 构造方法的作用?
在创建对象(new)的时候,可以完成属性的初始化。
3.7.3 构造方法语法规则
public class 类{
控制权限 类名(形参类型 变量 ,形参类型 变量2 ){
方法体;
}
}
注意:
1.权限任意,大多public
2.构造方法不需要任何返回声明,void 不需要
3.构造器的名字和类名完全一致
4.形参和方法体目的: 给属性初始化
public class Emp {
public int eno;
public String ename;
public double sal;
public String gender;
//快捷键 source > generate Constructor alt+insert
/**
* 构造方法,姓名和性别的初始化
*/
public Emp(String ename,String gender) {
this.ename = ename;
this.gender = gender;
}
public Emp(int eno, double sal) {
this.eno = eno;
this.sal = sal;
}
/**
* 构造方法,四个属性的初始化
*/
public Emp(int eno, String ename, double sal, String gender) {
this.eno = eno;
this.ename = ename;
this.sal = sal;
this.gender = gender;
}
/**
* 构造方法,无参数构造方法
*/
public Emp() {
System.out.println("创建了一个员工对象");
}
注意:
当构造方法的参数不同(参数个数,参数类型,参数顺序),共存的构造(构造方法的重载)
3.7.4 构造方法的调用
构造方法的调用是new对象的时候,一般用于类外部创建对象调用
Emp e = new Emp(); //调用本类的空构造 public Emp() {}
Emp e = new Emp(1,5000); //调用public Emp(int eno, double sal) {}
Emp e = new Emp(1,"王班长",6000,"男");//调用public Emp(int eno, String ename, double sal, String gender) {}
3.7.5 构造方法的类型
1.显式构造方法(手动自定义的构造方法)
2.隐式构造方法(系统默认的构造方法,当没有任何显式构造,系统为我们提供隐式构造)
public 类名(){
}
类名(){
}
注意:
当手动定义构造,隐式默认构造被覆盖,因此,一定注意:一旦定义构造,提供一个空构造
public class Product {
public int pno;
public String pName;
public double price;
//显式构造
public Product(int pno, String pName, double price) {
this.pno = pno;
this.pName = pName;
this.price = price;
}
//手动添加一个隐式,必添加一个
public Product() {
}
}
public class TestPro {
public static void main(String[] args) {
//此时调用默认隐式构造
Product p = new Product();
}
}
public OA() {
//初始化
emps[0] = new Emp(1, "王班长", 6000, "男");
emps[1] = new Emp(2, "康复班长", 4000, "男");
emps[2] = new Emp(3, "高雅慧", 9000, "女");
//调用menu
menu();
}
3.7.6 构造方法和普通方法的区别
构造方法 | 普通方法 | |
---|---|---|
返回声明 | 不需要 | 必须有: void / int… |
调用方式 | new对象时 | 对象. |
调用者 | JVM | 某对象 |
次数 | 一个对象调用1次 | 一个对象可以调用n次 |
作用 | 初始化对象属性 | 自定义 |
第四章 面向对象三大特性
面向对象的三大基本特性:封装性,继承性,多态性
1.封装性 代码封装,信息隐藏。 安全性
2.继承性 类的继承,代码继承。 避免代码重复和冗余
3.多态性 一个父类有多个子类 代码灵活,扩展性强
4.1 封装性
4.1.1 什么是封装?
将类中定义的属性,方法甚至构造方法,信息隐藏,不会暴露,不会非法使用。
4.1.2 封装的作用?
保证数据的安全性。(1.类的外部不能调用 2.不能非法调用)
4.1.3 如何实现封装?
1. 将需要封装的信息权限修改: 权限改为 私有的 private
权限:
public 公开的 整个项目
private 私有的 当前类
注意: 实际开发中,属性全部私有化,方法(构造)根据需求设定。
2. 需要为每一个属性提供两个公开的方法:setXX() 设置值 getXX() 获取值
/**
* 设置名字
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取名字
*/
public String getName() {
return name;
}
3. 在getXX() setXX()方法中添加存取条件
//添加限制
public boolean setLegs(int legs) {
if(legs > 0) {
this.legs = legs;
return true;
}else {
return false;
}
}
注意:
属性私有,在方法中判断来使用,避开非法使用。
4.1.4 封装方法和构造方法
封装方法: 类中某些方法只有类内部需要调用,不想暴露外部,封装方法
封装构造方法: 不允许外部实例化对象。
// TV : 品牌 尺寸 open() close()
package com.qf.oop;
public class TV {
private String type;
private int size;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public TV(String type, int size) {
super();
this.type = type;
this.size = size;
}
public TV() {
}
public void open() {
innerPart();
System.out.println("电视启动");
}
//封装的内部方法,只能当前类内部调用
private void innerPart() {
System.out.println("内部零件1 ....");
System.out.println("内部零件2 ....");
System.out.println("内部零件3 ....");
}
}
public class Earth {
//封装构造,不希望被实例化
private Earth() {
}
}
public final class Math {
/**
* Don't let anyone instantiate this class.
*/
private Math() {}
}
单例模式:
/**
* 单例模式
* @author 86136
*
*/
public class Earth {
private static Earth earth = new Earth();
private Earth() {
}
public static Earth getEarth() {
return earth;
}
}
public class TestEarth {
public static void main(String[] args) {
Earth e1 = Earth.getEarth();
Earth e2 = Earth.getEarth();
System.out.println(e1 == e2);
}
}
4.1.5 JAVA中属性的赋值顺序
思考: setXX() ,构造赋值不冲突
JAVA中属性的赋值顺序:
1. 默认值
2. 声明同时值
3. 构造方法
4. setXX() 多次调用,修改值
4.1.6 JAVA源文件的构成
Teacher.java
//包的声明,包相当于文件夹,包可以限制访问,方法类的存储
//package 用于声明包 首行
//包: 小写 .间隔 根包.子包 企业: 网站后缀.公司名.项目名.功能包.模块
package com.qf.oop;
//引入包 根包.子包.类; *全部
import java.util.*; //n个
import java.util.Arrays; //java api
import com.qf.meituan.Seller; //本项目跨包api
//类: public 或不加 / 接口
public class Teacher{
//属性
//方法
//构造
}
class A{
//属性
//方法
//构造
}
class B{
//属性
//方法
//构造
}
...
注意:
JAVA中很多包:
java.lang 核心包,不需要手动引入
java.util 工具包
java.io 文件输入输出
java.net 网络
java.awt 抽象窗口,图形界面
..
编码规范:
包名 小写 com.qf.oop;
类名 首字母大写 Student HelloWorld
属性 小写/驼峰 sNo name
方法 同上
常量 大写 MAXVALUE PI
变量 同属性
4.2 类和类之间关系
常见的类关系: 包含(关联),继承(泛化),依赖
//包含关系: A的属性是B类型 "有" has a
//关联关系 : 1对1 1对多 多对多
public class A{
private B b;
private B[] bb;
}
public class B{
}
案例:
//商家
public class Seller{
public Food[] foods;
}
//食物
public class Food{
}
常见: 学校有学生,客户和账户, 班级和班长,主人和猫…
//继承关系: B类具备A类的属性或方法 ”是“ is a
public class A{
}
public class B extends A{
}
常见: 动物类 老虎类 , 文具 钢笔 , 学生类 人类 , 交通工具 汽车
//依赖关系: A类需要借助B类实现行为 "用" use a
public class A{
public void test(B b){
}
}
public class B {
}
public class Student{
public void goToSh(Car c){
}
}
public class Car{
}
常见: 学生借助交通工具上学,飞行员开飞机…
案例:模拟客户的银行账户
类设计:
Account:
package com.qf.oop.bank;
public class Account {
private String ano;
private double balance;
private String pass = "111111";
public Account() {
}
public Account(String ano) {
super();
this.ano = ano;
}
public String getAno() {
return ano;
}
public void setAno(String ano) {
this.ano = ano;
}
public double getBalance() {
return balance;
}
public String getPass() {
return pass;
}
public boolean update(String pass) {
if(!this.pass.equals(pass)) {
this.pass = pass;
return true;
}else
return false;
}
/**
* 存钱
*/
public boolean deposit(double money) {
if(money > 0 && money % 100 == 0) {
balance += money;
return true;
}
else
return false;
}
/**
* 取钱
*/
public boolean withdraw(double money) {
if(balance>= money && money % 100 == 0) {
balance -= money;
return true;
}
else
return false;
}
@Override
public String toString() {
return "Account [ano=" + ano + ", balance=" + balance + ", pass=" + pass + "]";
}
}
Customer:
package com.qf.oop.bank;
import java.util.Arrays;
public class Customer {
private String name;
private String tel;
//关联 一对多
private Account[] acc= new Account[2];
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public Customer(String name, String tel) {
super();
this.name = name;
this.tel = tel;
}
public Customer() {
}
/**
* 开户
*/
public boolean setAcc(Account a) {
//统计几个空的
int count = 0;
for (int i = 0; i < acc.length; i++) {
if(acc[i] == null) {
count++;
}
}
System.out.println(count);
if(count == 2) {
acc[0] = a;
return true;
}else if(count == 1) {
acc[1] = a;
return true;
}else {
return false;
}
}
@Override
public String toString() {
return "Customer [name=" + name + ", tel=" + tel + ", acc=" + Arrays.toString(acc) + "]";
}
/**
* 根据卡号获取账户
*/
public Account getAcc(String ano) {
int index = -1;
for (int i = 0; i < acc.length; i++) {
if(ano.equals(acc[i].getAno())) {
index = i;
break;
}
}
if(index != -1) {
return acc[index];
}else {
return null;
}
}
}
Banking:
package com.qf.oop.bank;
import java.util.Scanner;
public class Banking {
/**
* 银行业务办理,依赖关系
*/
public Banking(Customer c) {
System.out.println("欢迎办理业务,你好:" + c.getName() );
Scanner sc = new Scanner(System.in);
while(true) {
System.out.println("1.开户");
System.out.println("2.销户");
System.out.println("3.进入账户");
System.out.println("请输入操作编号");
int opr = sc.nextInt();
if(opr == 1) {
//随机数100000-999999
int ano = (int)((999999 - 100000 + 1) * Math.random() + 100000);
Account acc = new Account("" + ano);
//设置账户
if(c.setAcc(acc)) {
System.out.println("开户成功,开户卡号:" + acc.getAno());
}else {
System.out.println("账户已满,无法开户");
}
}else if(opr == 2) {
}else if(opr == 3) {
System.out.println("请输入账号");
String ano = sc.next();
Account a = c.getAcc(ano);
if(a == null) {
System.out.println("账户不存在");
}else {
//存在
System.out.println(a);
//二级菜单
while(true) {
System.out.println("1.存钱");
System.out.println("2.取钱");
System.out.println("3.查余额");
System.out.println("4.转帐");
System.out.println("5.修改密码");
System.out.println("请输入操作编号");
int opr2 = sc.nextInt();
}
}
}else{
System.out.println("无此操作");
}
}
}
public static void main(String[] args) {
new Banking(new Customer("于小闹", "1231231"));
}
}
4.3 继承性
什么是继承?
代码的继承,将A类中定义的成员(属性+方法)被B类直接使用,JAVA中的继承。
4.3.2 继承的好处?
避免代码冗余,更加方便
4.3.3 继承的关系
A类中的代码被B类使用
A类 : 父类,根类,基类, 超类
B类 ; 子类,派生类,衍生类
B类{
//父类继承的成员
//子类原有的成员
}
4.3.4 如何实现继承?
语法规则:
控制权限 class 子类 extends 父类{
}
案例:
public class Person {
public String card;
public String name;
public void eat() {
System.out.println(name + "正在吃饭");
}
}
public class Student extends Person{
public String sNo;
}
public class TestStudent {
public static void main(String[] args) {
Student s = new Student();
s.name = "大野";
//System.out.println(s.card);
System.out.println(s.name);
//System.out.println(s.sNo);
s.eat();
}
}
4.3.5 继承后的特性
1.JAVA中继承关系: 单继承 (一个父类可以有子类,每个子类都只能是一个父类),多层结构(顶层抽象,底层具体)
2. JAVA中顶级根类: java.lang.Object 所有的类,直接或间接继承 Object
public class Person extends Object{
public String card;
public String name;
public void eat() {
System.out.println(name + "正在吃饭");
}
}
3. 继承什么? 子类可以继承整个祖先(父类,爷爷类)类中 : 非私有的属性和方法,不能继承构造方法
public class Person {
public String name;
public String gender;
public Person() {
}
public Person(String name, String gender) {
super();
this.name = name;
this.gender = gender;
}
public void sleep() {
System.out.println(name + "在睡觉");
}
}
public class Student extends Person{
public int sNo;
public void study() {
System.out.println(name + "学习");
}
}
public class Pupil extends Student{
public void play() {
System.out.println(name + "在玩游戏");
}
}
public class TestPerson {
public static void main(String[] args) {
Pupil p = new Pupil();
p.name = "斜彪";
p.study();
p.play();
}
}
4. java中继承影响权限访问
java中四种权限:public private protected default(缺省)
重点:
权限 | 含义 | 访问范围 |
---|---|---|
public | 公开的 | 访问范围 |
protected | 受保护的 | 本包访问,跨包但是有继承关系可以访问 |
defaul(缺省) | 友好的 | 本包友好,本包访问 |
private | 私有的 | 本类访问 |
public class A {
public int i = 10;
protected int j = 10;
int k = 10;
private int m = 10;
}
//同包
public class B {
public void test() {
A a = new A();
System.out.println(a.i);
System.out.println(a.j);
System.out.println(a.k);
//System.out.println(a.m);
}
}
//跨包
public class D extends A{
public void test() {
System.out.println(i);
System.out.println(j);//子类被保护
//System.out.println(k);
//System.out.println(m);
}
}
public class C {
public void test() {
A a = new A();
System.out.println(a.i);
//System.out.println(a.j);
//System.out.println(a.k);
//System.out.println(a.m);
}
}
注意:
权限的修饰
类/接口:public 缺省
属性:四个
方法:四个
构造:四个
局部变量:不加权限
权限的范围顺序:
public > protected > default > private
4.3.6
1.属性的覆盖(了解,开发中不会有)
public class Person {
public String name = "老王";
}
public class Pupil extends Person{
public String name = "小小王";
}
public class TestPerson {
public static void main(String[] args) {
Pupil p = new Pupil();
System.out.println(p.name);//小小王,覆盖
Person p2 = new Person();
System.out.println(p2.name);//老王 ; 子类不能修改父类的特性
}
}
2.方法的覆盖(子类对父类的行为加以修改,又叫做重写@Override)
方法重写(覆盖)的基本原则:
1.方法名相同
2.方法的参数必须相同
3.方法的返回值必须相同
4.权限不能降低
3.方法的重载(相同方法根据实参实现多样化 Overload)
方法重载的基本原则:
1.方法名相同
2.方法的参数必须不同
3.方法的返回值无限制
4.权限不限制
public class Person {
public void sleep() {
System.out.println(name + "在睡觉");
}
}
public class Student extends Person{
//重写父类方法
@Override
public void sleep() {
System.out.println(name + "在上课的睡觉");
}
//重载
int sleep(int hour) {
return 10;
}
//重载
int sleep(double hour) {
return 10;
}
//重载
int sleep(double hour,String a) {
return 10;
}
}
重载和重写对比:(重点)
重载 | 重写(覆盖) | |
---|---|---|
参数 | 必须不同 | 必须相同 |
返回值 | 没有限制 | 必须相同 |
权限 | 没有限制 | 不能降低权限 |
次数 | n次 | 1次 |
位置 | 本类 | 父子类 |
抛出异常 | 没有限制 | 子类不能抛出更多异常 |
构造方法 | 可以 | 不能 |
子类覆盖父类的方法后,如何调用父类的资源?
super.方法(); //子类覆盖父类方法,需要在子类中获取父类方法
public class Father {
private int a = 10;
private int b = 20;
public int sleep() {
System.out.println("爸爸睡觉:");
return 10;
}
@Override
public String toString() {
return "[a=" + a + ", b=" + b + "]";
}
}
public class Son extends Father{
private int c = 30;
@Override
public int sleep() {
//获得父亲睡眠时间
//调用父类中被覆盖的属性/方法
System.out.println(super.sleep());
System.out.println("儿子睡觉:");
return 12;
}
@Override
public String toString() {
return super.toString() + " [c=" + c + "]";
}
}
4.3.7 继承中的构造方法
1. JAVA中继承关系:构造方法不能被继承,只能调用
2.子类中,需要调用父类的某个构造方法:
super([参数1,参数2...]); //调用父类的有参数构造
super(); //调用父类的有参数构造
public class Animal {
private String type;
private int age;
public Animal(String type) {
//调用Object的空构造
super();
this.type = type;
}
public Animal(String type, int age) {
this.type = type;
this.age = age;
}
@Override
public String toString() {
return "Animal [type=" + type + ", age=" + age + "]";
}
}
public class Dog extends Animal{
private String sound ;
public Dog(String type,int age,String sound) {
//调用父类的构造方法
super(type,age);
this.sound = sound;
}
public Dog(String type,String sound) {
//调用父类的构造方法完成属性的初始化
super(type);
//初始化自己定义的属性
this.sound = sound;
}
@Override
public String toString() {
return super.toString() + "sound=" + sound + "]";
}
}
3.构造方法默认执行顺序
Object构造 > 祖先构造器 > 父类构造器 > 子类构造器
4.JAVA中,任何构造方法的第一行都会有super()调用(显式调用 / 默认隐式调用)
public 类(){
//super(参数);
super();//默认存在,调用父类的空构造
}
5.因此,写类的构造方法的时候,一定提供提供空构造方法,子类super()调用就会出错。
public class Animal {
public Animal() {
super();
System.out.println("动物出生啦");
}
}
public class Dog extends Animal{
public Dog() {
//super();
System.out.println("狗出生啦");
}
}
public class HaDog extends Dog{
public HaDog() {
super();
System.out.println("哈士奇出生啦");
}
}
public class TestDog2 {
public static void main(String[] args) {
new HaDog();
//动物出生啦
//狗出生啦
//哈士奇出生啦
}
}
4.3.8 super和this的用法
super:用于在子类中调用父类的成员
//1 super调用父类的属性(覆盖)
super.属性
//2 super调用父类的方法(覆盖)
super.方法();
//3.super() 调用父类的构造方法: 必须将调用放在构造方法的第一行
super(参数);
super();
public Student() {
//super();
}
public Student(String name, String gender,int sNo) {
super(name, gender);
this.sNo = sNo;
}
this:某个类的当前对象,用于当前类
//1. 全局变量被局部变量覆盖,this.属性
public class Student extends Person{
public int sNo;
public Student(String name, String gender,int sNo) {
super(name, gender);
this.sNo = sNo;
}
}
//2.本类调用属性和方法
public void study() {
System.out.println(this.name + "学习");
this.sleep();
}
//3. this可以调用本类的构造方法: 必须放在构造方法的首行,不允许和super()
this(参数);
public Account(String ano, String pass, double balance) {
//调用public Account(String ano, String pass) {}
this(ano,pass);
this.balance = balance;
}
public Account(){
}
public Account(String ano, String pass) {
super();
this.ano = ano;
this.pass = pass;
}
练习:
请编码实现动物世界的继承关系:
动物(Animal)属性: 动物名字 年龄 具有行为:吃(eat)、睡觉(sleep)
动物包括:兔子(Rabbit),老虎(Tiger)
这些动物吃的行为各不相同(兔子吃草,老虎吃肉);但睡觉的行为是一致的。
请通过继承实现以上需求,并编写测试类AnimalTest进行测试
多态性
4.4.1 什么是多态?
广义的来说:一个父类呈现出多种子类形态,称之为多态:交通工具父类:汽车,公交车,飞机
狭义的来说:父类类型的变量指向某个子类的实例化对象(子类的实例化对象赋值给父类类型变量)
父类 多态对象 = new 子类(); //对象向上转型
Vehicles v = new Truck();
v = new Bus();
v = new Car();
4.4.2 多态的好处?
代码设计更加灵活,方便扩充。
4.4.3 多态的底层分析
Vehicles v = new Truck();
1.从编译角度分析
类型转换(引用类型有继承关系时)
强制转换 子类 对象 = (子类) new 父类(); // 运行时报出java.lang.ClassCastException
自动转换 父类 对象 = new 子类();
2.从编译和运行的机制分析
Car c = new Car();
Vehicles v = new Car();
Car c2 = new Vehicles();
4.4.4 对象向上转型
父类 多态对象 = new 子类();
多态对象的访问:
只能访问父类的属性/方法;当且仅当子类覆盖父类的方法(调用子类)
public class Vehicles{
private String brand;
private String color;
public int a = 10;
public void run(){
System.out.println("我已经开动了");
}
}
public class Car extends Vehicles {
private int seats;
public int a = 20;
public void run() {
System.out.println("小汽车跑起来");
}
}
public class Bike extends Vehicles {
private int seats;
public int a = 30;
public void run() {
System.out.println("自行车跑起来");
}
}
public class Test {
public static void main(String[] args) {
//多态对象
Vehicles v = new Car();
System.out.println(v.a);// 10
v.run();//小汽车跑起来
}
}
4.4.5 多态如何实现?
多态的形成条件(重点):
1.继承(一个父类多个子类)
2.子类覆盖父类方法
3.对象向上转型
4.4.6 多态的应用体现
方法的传参: 引用数据类型 (依赖关系)
public class A{
public void xx(父类类型 变量){
}
xx(子类对象);
}
public class Student {
private String name;
/**
* 去上学: 借助交通工具 》 依赖
*/
public void toSchool(Vehicles v) {
System.out.println(name + "去上学");
v.run();
}
public static void main(String[] args) {
new Student("小范同学").toSchool(new Plane());
}
}
练习:
父类 : USB设备 work(){}
子类: Mouse Key U 覆盖
程序员类 : 使用USB (USB u)
测试程序员使用: 使用键盘...
4.4.7 对象向下转型
为了多态对象在使用当中,获取某个子类中行为。
//向下转型
KeyBoard k = (KeyBoard)u;
k.light();
Account a1 = new CheckingAccount(3000,1000);
CheckingAccount c1 = (CheckingAccount)a1;
System.out.println(c1.getProtect());
注意: 向下转型,一定注意类型的匹配(编译类型和运行类型是否匹配)
引用类型判断的关键字:
instanceof
语法规则:
引用类型变量 instanceof java类/接口
结果:boolean
true 变量属于JAVA类型或JAVA类的子类类型
false
注意:
1.所有变量检测Object,都为true
2.instanceof 只用于有继承关系的检测
3.JAVA中的多个子类之间没有任何联系
public class Banking {
public static void main(String[] args) {
Account a1 = new Account();
CheckingAccount c1 = new CheckingAccount();
//Account a1 = new CheckingAccount(3000,1000);
//CheckingAccount c1 = (CheckingAccount)a1;
//System.out.println(c1.getProtect());
System.out.println(a1 instanceof Account);//true
System.out.println(a1 instanceof CheckingAccount);//false
System.out.println(c1 instanceof Account);//true
System.out.println(c1 instanceof CheckingAccount);//true
System.out.println(a1 instanceof Object);
System.out.println(c1 instanceof Object);
//System.out.println(c1 instanceof SavingsAccount);
}
}
实现:
//向下转型
Account a = c.getAcc();
if(a instanceof CheckingAccount) {
CheckingAccount ck = (CheckingAccount)a;
System.out.println("透支额度:" + ck.getProtect());
}
第五章 面向对象高级特性
三个修饰符:abstract final static
接口:interface
枚举:enum
5.1 抽象的 abstract
5.1.1 什么是abstract?
抽象的,无法描述清楚,无法具体化的事物,似是而非的,比较笼统的。
5.1.2 abstract修饰什么?
修饰类 : 抽象类
控制权限 abstract class 类名{}
public abstract class Fly {
}
修饰方法 : 抽象方法
控制权限 abstract 返回值 方法名(参数) ;
5.1.3 抽象类
特点:
1. 抽象类一般用于难以描述的事物,用于父类
2. 抽象类不能实例化对象,一定要有构造方法,给子类调用
3. 抽象类中可以抽象方法或非抽象方法,但是包含抽象方法所在的类一定是抽象类。
4. 抽象类强制要求必须有子类继承,否则没有意义
/**
* 抽象父类
* @author 86136
*
*/
public abstract class Shape {
//属性 形状名
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Shape() {
}
public Shape(String name) {
super();
this.name = name;
}
/**
* 画出形状
*/
public abstract void draw();
/**
* 面积
*/
public abstract double getArea();
}
5.1.4 抽象方法
1. 抽象方法没有方法体
2. 子类继承抽象父类,一定将抽象方法覆盖,否则该子类成抽象类
public class Circle extends Shape{
private int r;
/**
* 获得圆的面积
*/
public double getArea() {
return Math.PI * r * r;
}
public void draw() {
System.out.println("画出" + getName());
}
public Circle() {
super();
// TODO Auto-generated constructor stub
}
public Circle(String name,int r) {
super(name);
this.r = r;
}
}
public class Student {
public void calc(Shape s) {
s.draw();
// if(s instanceof Circle) {
// System.out.println("面积:" + ((Circle)s).getArea());
//
// }
// if(s instanceof Rect) {
// System.out.println("面积:" + ((Rect)s).getArea());
// }
System.out.println(s.getArea());
}
}
总结:
抽象: 可以修饰:类和方法
抽象类强制要求继承,抽象方法强制要求覆盖,对象向上转型。
5.2 最终的 final
5.2.1 什么是final?
最终的,最后的,到它结束了。
5.2.2 final可以修饰什么
1. 类
public final class TestFinal {
}
2. 变量(全局+局部)
final 数据类型 变量名 = 值;
3. 方法
public final void test() {
}
5.2.3 final修饰的特点
1. 类 不能有子类的,最终的类/可以创建对象
2. 变量 常量,不能修改值,常量全大写
修饰属性的时候: 必须给初始值
public final class TestFinal {
public final double MYPI = 3.14;
}
3. 方法 不能被重写
public class TestFinal2 {
public final int A = 100;
public final void test() {
}
}
class TestFinal3 extends TestFinal2{
// public void test() {
//
// }
}
5.3 静态的 static
5.3.1 什么是static ?
静态的,属于类本身的,人(年龄 姓名 性别 种族(灵长目) ),当属性/方法属于类本身的,不会随着对象发生变化,这样的属性和方法是静态的(类的)。随着对象发生变化的属性/方法(非静态的/实例的)。
5.3.2 static能修饰什么 ?
属性:静态属性/类属性
public static int b = 20;
方法:静态方法/ 类方法
public static void test2() {
}
内部类:类中的类
5.3.3 静态属性的特点
案例:
public class TestStatic {
//实例属性
public int a = 10;
//静态属性
public static int b = 20;
public TestStatic() {
a ++;
b ++;
}
public static void main(String[] args) {
TestStatic t1 = new TestStatic();
System.out.println(t1.a + "," + TestStatic.b); // 11 21
TestStatic t2 = new TestStatic();
System.out.println(t2.a + "," + TestStatic.b);// 11 22
}
}
静态属性的特点:
1.归类所有,不属于某个对象,一份资源拷贝,静态区,所有的对象共享资源
2.静态属性(类属性)是在类加载之前初始化完毕。
静态(类)属性 | 实例属性 | |
---|---|---|
开辟空间 | 静态区 | 堆 |
归属 | 类(对象共享) | 对象 |
初始化时间 | 类加载 | 创建对象的时候 |
调用方式 | 类.属性(推荐)对象.属性 | 对象.实例属性 |
5.3.4 静态方法的特点
1.静态方法当中,只能访问静态成员(静态属性 / 静态方法)
2.需要访问:必须创建对象
类.静态方法() 如:Math.random()
3.在实例方法中,可以任意访问静态方法的。
public class TestStatic2 {
public int a = 1 ;
public static int b = 2;
public void t1() {
this.t2();
}
public void t2() {
t3();
}
public static void t3() {
t4();
}
public static void t4() {
System.out.println(b);
//调用非静态,创建对象
new TestStatic2().a = 20;
}
public static void main(String[] args) {
new TestStatic2().a = 20;
}
}
5.3.5 静态代码块
用于在类中初始化静态属性的。
语法规则:
static{
//初始化静态属性
}
注意:
调用机制:只调一次,类加载之前
个数:可以有多个,按照声明顺序一次执行
实例代码块:初始化实例属性
{
}
执行顺序: 静态代码块(1次) > 实例代码块(n次) > 构造方法(n次)
public class TestStatic3 {
public static int a = 20;
public int b ;
//实例代码块
{
b = 30;
System.out.println("实例代码块" + b);
}
//静态代码块
static {
System.out.println("静态代码块");
}
static {
System.out.println("静态代码块2");
}
//构造方法
public TestStatic3() {
System.out.println("构造");
}
public static void main(String[] args) {
new TestStatic3();
new TestStatic3();
}
}
5.4 修饰词公用
//不能共用
1. abstract 和 final 不能共同修饰类/方法
2. abstract 和 private 不能共同修饰方法
3. abstract 和 static 不能共同修饰方法
// 可以共用
static final
修饰属性: public static final double PI = 3.14159265358979323846;
1.必须初始值
2.Math.PI
修饰方法: public static final void test() {
System.out.println("测试方法");
}
5.5 接口
5.5.1 什么是接口?
第三种引用数据类型,一种能力或者行为的定义,一种特殊的“抽象类”。
5.5.2 接口的作用
解决单继承
职责解耦(设计和实现分离),接口是设计层面,只谈约定能力,类是实现层面,真正实现功能。 what / how
坦克:交通工具,单继承,坦克不具备武器功能,单一化
5.5.3 接口的声明
控制权限 interface 接口名{
}
控制权限: public 缺省
接口名: 首字母大小写合法标识符,IPerson
5.5.4 接口的实现
语法:
控制权限 class 实现类 extends 父类 implements 接口1,接口2...{
}
public interface IWeapon{
}
public interface IVehicles{
}
public class Iron{
}
public class Tank extends Iron implements IWeapon,IVehicles{
}
5.5.5 接口的成员
1.属性:公开的静态常量 public static final
2.方法:公开的抽象方法 public abstract (jdk8-)
注意:接口中方法属性的修饰词/权限 都可以省略,即使省略,默认该类型
/**
* jdk8+ 非抽象: 相同行为
*/
public default void fix() {
System.out.println("维修工具");
}
5.5.6 接口的成员调用
属性 : 接口.属性
方法 : 实现类实现接口,覆盖抽象方法,否则该类变成抽象类,实现类调用
注意:
接口不能创建对象,没有构造方法
public interface IWeapon {
//public static final
int POWER = 100;
/**
* 开火
*/
//public abstract
//默认抽象的
void fire();
}
public class Tank extends Iron implements IWeapon,IVehicles{
@Override
public void fire() {
System.out.println("坦克突突突");
}
}
public abstract class Transport implements IVehicles{}
public class Car extends Transport{
@Override
public void run() {
System.out.println(getColor() + "的" + getType() + "开起来");
}
}
public class TestWeapon {
public static void main(String[] args) {
System.out.println(IWeapon.POWER);
IWeapon w = new Tank();
w.fire();
}
}
5.5.7 接口中的多态
1. 一个接口多个实现类(接口是设计,实现类实现)
2. 实现类实现接口,必须覆盖
3. 向上转型 (接口类型 多态对象 = new 实现类对象() )
4. 向下转型判断 > instanceof
public interface IFly {
/**
* 起飞
*/
void takeOff();
/**
* 着落
*/
void land();
}
public class Plane implements IFly{
private String name ;
public Plane() {
}
public Plane(String name) {
super();
this.name = name;
}
@Override
public void takeOff() {
System.out.println(name + "客机起飞");
}
@Override
public void land() {
System.out.println(name + "客机着落");
}
}
public class Helicopter implements IFly{
@Override
public void takeOff() {
System.out.println("直升机起飞");
}
@Override
public void land() {
System.out.println("直升机着落");
}
}
public class Pilot {
private String name;
public Pilot(String name) {
super();
this.name = name;
}
/**
* 驾驶: 多态设计
*/
public void drive(IFly fly) {
System.out.println(name + "主驾驶");
fly.takeOff();
fly.land();
}
public static void main(String[] args) {
new Pilot("小小君").drive(new Plane("MH370"));
}
}
//向下转型
if(fly instanceof Plane) {
System.out.println("欢迎旅客.....");
Plane e = (Plane)fly;
e.eating();
}
5.5.8 接口和接口的关系
类与类 : 单继承 extends
类与接口 : 多实现 implements
接口与接口: 多继承 extends
语法:
控制权限 interface 子接口 extends 父接口1,父接口2..{
}
public interface A extends B,C{
}
interface B{
}
interface C{
}
练习:
/**
* 父接口: 生物 ICreature 呼吸breath()
* 细胞 ICell
*子接口: 动物 Animal (吃饭 睡觉)
* 植物 Plant
*子接口 : 人 (思考 think)
*
*学生实现类 : 学习
*
* 测试学生
* @author 86136
*
*/
public class TestCreature {
public static void main(String[] args) {
Person p = new Student("小王");
p.breath();
p.eat();
p.sleep();
p.think();
((Student)p).study();
}
}
interface ICreature{
void breath();
}
interface ICell{
}
interface Animal extends ICell,ICreature{
void sleep();
void eat();
}
interface Plant extends ICell,ICreature{
}
interface Person extends Animal{
void think();
}
class Student implements Person{
private String name;
public Student() {
}
public Student(String name) {
super();
this.name = name;
}
@Override
public void sleep() {
System.out.println(name + "睡觉");
}
@Override
public void eat() {
System.out.println(name + "吃饭");
}
@Override
public void breath() {
System.out.println(name + "呼吸");
}
@Override
public void think() {
System.out.println(name + "思考");
}
public void study() {
System.out.println(name + "学习");
}
}
5.5.9 接口和抽象类的区别
区别:
接口 | 抽象类 | |
---|---|---|
构造方法 | 没有 | 有 |
类关系 | 多实现 | 单继承 |
属性 | 静态常量 | 静态/非静态 |
方法 | 抽象 / default | 抽象/非抽象的 |
相似:
1.都不能实例化对象
2.都需要后代,方法覆盖
5.6 枚举以及工厂模型
第四种引用数据类型,是应用于列举固定的离散值。
例如: 性别: 男 女 。 交通灯颜色: 红 黄 绿 。 月份: 1-12 。 四季 , 56民族。
5.6.1 枚举的作用?
固定住类型,限制类型的使用
5.6.2 枚举的声明
控制权限 enum 枚举名{
}
public 缺省
class interface enum
枚举名: 同类/接口 RequetType
5.6.3 枚举的成员
只定义常量,枚举类型的
public enum GenderType {
//常量名
BOY,GIRL;
}
5.6.4 枚举的成员访问
枚举.常量
案例:
public enum GenderType {
BOY,GIRL;
}
public class TestGender {
public static void main(String[] args) {
//System.out.println(GenderType.BOY);
scanner(GenderType.GIRL);
}
/**
* 需要使用性别
*/
public static void scanner(GenderType type) {
System.out.println("您的性别:" + type);
}
}
练习:
/**
* DOC, TXT, JPG
*
* 方法: 上传方法(文件类型)
* @author 86136
*
*/
public enum FileType {
DOC, TXT, JPG
}
public class Upload {
/**
* 文件上传
*/
public static void fileUpload(FileType type) {
System.out.println(type + "格式文件上传成功");
}
public static void main(String[] args) {
fileUpload(FileType.JPG);
}
}
设计模式: 23种设计模式
//单例模式 (对象实例1个)
public class Earth {
private static Earth earth = new Earth();
private Earth() {
}
public static Earth getEarth() {
return earth;
}
}
//静态工厂模型
public enum ShoesType {
NIKE,ANTA,LINING;
}
public interface Shoes {
void produce();
}
public class Nike implements Shoes{
@Override
public void produce() {
System.out.println("耐克批量生产");
}
}
public class Anta implements Shoes{
@Override
public void produce() {
System.out.println("安踏批量生产");
}
}
public class LiNing implements Shoes{
@Override
public void produce() {
System.out.println("李宁批量生产");
}
}
public class ShoesFactory {
// 多态
private static Shoes shoes;
// 多态返回值
public static Shoes getProduct(ShoesType type) {
switch (type) {
case NIKE:
shoes = new Nike();
break;
case ANTA:
shoes = new Anta();
break;
case LINING:
shoes = new LiNing();
break;
}
shoes.produce();
return shoes;
}
}
public class TestShoes {
public static void main(String[] args) {
Shoes shoe = ShoesFactory.getProduct(ShoesType.NIKE);
}
}
5.7 内部类
5.7.1 内部类简介
类里面定义类,分成三种:全局静态内部类,全局非静态内部类,局部内部类
package com.qf.oop;
/**
* 外部类
* @author 86136
*
*/
public class Outer {
//全局静态
public static class Inner1{
public static int a = 10;
public int b = 20;
}
//非静态,实例
public class Inner2{
public int c = 30;
}
public void test() {
//局部内部类
class Inner3{
int d = 40;
}
Inner3 i3 = new Inner3();
System.out.println(i3.d);
}
}
测试:
public class TestInner {
public static void main(String[] args) {
//System.out.println(Outer.Inner1.a);
//Outer.Inner1 i1 = new Outer.Inner1();
//System.out.println(i1.b);
// Outer.Inner2 i2 = new Outer().new Inner2();
// System.out.println(i2.c);
new Outer().test();
}
}
5.7.2 匿名内部类
特殊内部类,创建的类没有名字。
语法规则:
抽象父类/接口 多态对象 = new 抽象父类/接口(){
//抽象父类子类/接口的实现类类体
};
public interface IAnimal {
void eat();
}
public class TestAnimal {
public static void main(String[] args) {
//IAnimal a = new Tiger();
//a.eat();
//匿名类
IAnimal a = new IAnimal() {
@Override
public void eat() {
System.out.println("老虎吃肉");
}
};
//lambda 表达式,jdk8新特性
//必须用于接口,只有一个抽象方法
IAnimal a2 = () -> System.out.println("老虎吃肉");
a2.eat();
}
}
注意:
省略继承的类名,要覆盖的方法名
第六章 JAVA API(application programming interface)
概述:
java.lang : String StringBuffer StringBuilder Math 异常类 包装类
Object 线程类 Class
java.util : 集合类 日期类 工具类 Arrays
java.io : 文件类 流
6.1 异常类
6.1.1 什么是异常?
程序中出现问题。Throwable分为两类:
错误:Error (程序中出现致命问题,程序员编码不需要解决: 内存堆栈溢出,JVM崩了,系统崩了)
异常:Exception (程序员疏忽造成,需要解决)
6.1.2 异常的分类
Exception
编译时异常: 编译时发生异常(IOException SQLException FileNotFoundException)
运行时异常: 编译时不发生异常,运行抛出异常
RuntimeException
数组下标越界 java.lang.ArrayIndexOutOfBoundsException
算术异常: java.lang.ArithmeticException
类型转换异常: ClassCastException
空引用: NullPointerException
数字转换: NumberFormatException
...
6.1.3 异常发生如何?
1.程序终止
2.打印错误信息
3.内存分配的信息不变,导致信息泄露
6.1.4 异常捕获机制
语法:
try{
//监视器,监视有可能会发生异常的代码
}catch(异常类型 变量){
//捕获器,专用于捕获对应类型的异常
}catch(异常类型 变量){
}...
finally{
//最终执行块,无条件运行
}
注意:
- try 不可以单独,配合catch,或finally
- try可以对应多个catch,多个catch并列,多选一,从上往下,Exception类型放在最后
- finally 语句块可有可无,一旦有,无条件运行(不论是否发生异常)
- 程序发生异常,进入catch,捕获后,程序不会走回头路,继续向下运行,直到修改异常后。
练习:
//定义一个类,商品信息
public class Product{
//单价 price
//方法 传入一个数量字符串,返回总价
public static double getSum(String count){
//串转化数字 Integer.parseInt()
//捕获
}
}
6.1.5 异常抛出
异常从方法中抛出去:
throws 方法内存在异常,方法本身不解决,将异常类型向外抛出
抛出异常类型
throw 手动构建一个异常,引起注意
抛出异常对象
通常用于设计逻辑合理;年龄不是负的吗,性别只能是男女
throws 语法规则:
控制权限 修饰符 返回值 方法名(参数) throws 异常类型1,异常类型2 {
}
public static void test()throws ArithmeticException,Exception{
System.out.print(10/0);
}
注意:
- 抛出异常类型
- 抛给方法调用者,谁调用谁解决
- 通常编译时抛出的多
- 子类覆盖方法抛出的异常类型不能更大
// 错的
public class A{
public void test() throws ArithmeticException{
}
}
class B extends A{
public void test() throws Exception{
}
}
throw 手动构建异常 语法规则:
// 1.创建异常对象
异常类型 对象名 = new 异常类型(); // Exception e = new Exception();
// 2.抛出对象
throw 对象名; // 此处是异常,需要解决
public class TestException3 {
public static void checkAge(int age) throws Exception{
if(age >= 0) {
System.out.println("年龄正确");
}else {
//构造异常
Exception e = new Exception("年龄非法,不能是负的");
//手动抛出异常对象
throw e;
}
}
public static void main(String[] args) {
try {
checkAge(-9);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("lalaallal");
}
}
练习:
River 河流
当前水位 waterLine
警戒水位 warnnigLine
方法: flow() 判断水位溢出,不要捕获,抛出
waterLine warnnigLine超出10 创造异常 决堤
10以内 水静静流
测试类: 捕获
6.1.6 自定义异常
public class AgeException extends Exception{
}
throw new AgeException();
6.2 String
JAVA中字符串封装的类型。“” 归为一类 String.
public final class String extends Object implements Serializable, Comparable<String>, CharSequence{
}
// String 不可以有子类
6.2.1 字符串的创建
//String类型,和其他引用类型比,非常特殊
//1. 字符串常量对象 ""括起来的 常量对象 开辟内存(字符串常量池),不能修改
String s = "abc"; // 常量池
s = "abcd";
//2 字符串变量
new String();
new String("abc");
//abc一个对象实例
String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2); // true
String s3 = new String("abc");
String s4 = new String("abc");
System.out.println(s3 == s4); //false
String s = "abc";
String s2 = new String("abc");// 两个对象 "abc" s2指向对象
String s = "abc";
String s2 = new String("abcd");// 3个对象 "abc" s2指向对象 "abcd"
6.2.2 字符串的方法
方法名 | 含义 | 返回值 |
---|---|---|
length() | 字符串长度 | int |
charAt(下标) | 根据下标获取字符,下标 0-s.length() -1 | 返回位置上字符 char |
substring(begin) substring(begin,end) | 开始截取到最后 begin截取到end-1 | 返回新的子串String,没有改变原串 |
indexOf(子串) | 查找,左向右 | 返回第一次出现的下标 int,没有返回-1 |
lastIndexOf(子串) | 返回最后一次出现的下标 int,没有返回-1 | |
split(切割符号) | 切割,注意转义 \\ | String[] |
equals(字符串) | 值是否相同 | true/false |
compareTo(字符串) | 按照字典顺序比较 | 正 负 0 |
endsWith(子串) | 判断是否是以xx结尾 | true/false |
replace(old,new) | 替换 | |
trim() | 去掉字符串两端空格(中间不行) | |
matches(String regex) |
/**
* 设计一个方法,截取
* 传入一个字符串,返回该串后三位
*/
public static String getSub(String str) {
if(str.length() < 3) {
return str;
}
return str.substring(str.length() - 3);
}
/**
* 设计方法: 隐藏ip地址
* 传入192.168.10.158
* 返回 192.168.10.*
* @param args
*/
public static String hideIp(String ip) {
//int index = ip.lastIndexOf(".");
//return ip.substring(0,index) + ".*";
String[] arr = ip.split("\\.");
arr[arr.length - 1] = "*";
String s = "";
for (String p : arr) {
s += p + ".";
}
return s.substring(0,s.length() -1);
}
字符串比较:
String[] a = {"cat","apple","monkey","dog","liu"};
//按照字典顺序排序 apple cat .... 冒泡/选择
for (int i = 1; i < a.length; i++) {
for (int j = 0; j < a.length - i; j++) {
if(a[j].compareTo(a[j + 1]) > 0) {
String temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
System.out.println(Arrays.toString(a));
总结:
1.查找 indexOf() lastIndexOf()
2. 替换 replace()
3. 切割 split()
4. 截取 substring() charAt()
5. 比较 equals() compareTo()
String 不可变字符串,定义后不能修改
6.3 StringBuilder和StringBuffer
6.3.1 可变字符串存在意义
//a-z拼接输出
String str = "";
for (char i = 'a'; i <= 'z'; i++) {
str += i;
}
System.out.println(str);
//效率低
String 不可变字符串
StringBuilder和StringBuffer可变字符串,可以在原串基础修改,删除,插入(字符串缓存区)
StringBuilder 线程不安全,不同步,效率高,Buffer的替换,速度快
StringBuffer 线程安全,效率低
6.3.2 StringBuilder
new StringBuilder() ; //缓冲容量16
new StringBuilder(容器大小c) ; //缓冲容量c
new StringBuilder(String s) ; //16+s.length()
StringBuilder s1 = new StringBuilder();
StringBuilder s2 = new StringBuilder(25);
StringBuilder s3 = new StringBuilder("abc");
System.out.println(s1.capacity());//16
System.out.println(s2.capacity());//25
System.out.println(s3.capacity());//19
方法:(增删改)
方法 | 含义 | 返回值 |
---|---|---|
capacity() | 返回缓冲容量 | int |
append(参数) | 字符串缓冲区末尾追加内容 | StringBuilder |
insert(下标,内容) | 在下标之前插入内容 | StringBuilder |
delete(s,e) | 从s删除到e-1 | |
deleteCharAt(下标) | ||
setCharAt(下标) | 根据下标修改某字符 | void |
reverse() | 翻转字符串 |
StringBuilder s = new StringBuilder();
for (int i = 97; i <= 122; i++) {
s.append((char)i);
}
System.out.println(s);
6.3.3 正则表达式(了解)
正则表达式:规定好的固定的表达形式。
语法:
边界: ^ 开始 $ 结束
内容: ^0411-$ / 范围: ^[abc]-$ abc任选一个 [0-9] 0-9区间任选一个
位数: {n} n位
{n,m} n~m位
{n,} n位以上
特殊:
\d [0-9]
\w [0-9a-zA-Z_]
? 0或1
* 0或n
+ 1或n
6.4 Math
数学相关的方法。Math不能实例化对象,所有属性方法全静态。
private Math(){}
方法:
方法名 | 含义 | 返回值 |
---|---|---|
random() | 随机数[0~1]随机小数 | double |
round() | 四舍五入 Math.floor(a+0.5d) | int/long |
floor(num) | 向下取整 | double |
ceil(num) | 向上取整 | double |
pow(a,b) | a的b次幂 | |
sqrt(num) | 平方根 |
注意:
[a-b]随机数
(int)((b-a+1)*Math.random()+a)
6.5 八个包装类
6.5.1 将八个基本数据类型封装成八个类
基本类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
6.5.2 装箱拆箱转换
// 装箱 基本类型 > 包装类
//基本类型
int a = 10;
//自动装箱
Integer i = a;
//手动装箱
Integer i2 = new Integer(a);
//自动装箱的时候必须完全匹配
Double d = 10.0;
// 拆箱 包装类 > 基本类型
Double d = 10.0;
//自动拆箱
double d2 = d;
public class TestWrapper2 {
public static void main(String[] args) {
//常量池常量
Integer a = 10;
Integer b = 10;
System.out.println(a == b);//true
//128开辟对象
Integer c = 129;
Integer d = 129;
System.out.println(c == d);//false
Integer e = new Integer(10);
Integer f = new Integer(10);
System.out.println(e == f);//false
}
}
6.5.3 和字符串转换
// 转化为字符串
int a = 10;
Integer i = a;
//1 变量拼接
System.out.println(a + "");
//2.对象toString()
System.out.println(i.toString());
//3. String的valueOf()
System.out.println(String.valueOf(a));
// 转化为数字类型
Integer.parseInt(字符串);
Double.parseDouble(String s) ;
//异常 NumberFormatException
String s = "120.56";
//System.out.println(Integer.parseInt(s) * 20);
System.out.println(Double.parseDouble(s) + 200);
6.6 Object
所有类的默认根类,所有的类默认继承该类。
public class Student extends Object{
public Student() {
super();//调用Object构造方法
}
}
方法:
方法 | 含义 | 返回值 |
---|---|---|
equals() | 判断两个对象是否相同(引用),如果需要根据条件判断,重写 | boolean |
finalize() | 垃圾回收方法,JVM自动调用,需要其他清除,重写 | void |
hashCode() | 返回对象唯一哈希码,唯一标志对象 | |
toString() | 对象默认调用,哈希值转化16进制,子类覆盖 |
final 修饰符,修饰变量,类,方法,最终的
finally{} 语句块 ,异常捕获机制无条件执行
finalize() 方法,垃圾回收的
6.7 集合类(java.util,重点)
java.util 工具类
6.7.1 什么是集合?
实现数据存储的介质,可以数据更新(增 删 改 ),对象型数据存储,集合的元素的默认类型Object。
6.7.2 集合的体系结构
6.7.3 ArrayList
线性存储,可扩容的数组,默认开辟空间10.
创建:
new ArrayList(); //默认容量 10
new ArrayList(int); //给容量
new ArrayList(Collection c) ;
List<String> l = Arrays.asList("苹果","香蕉","橘子","咖啡");
//ArrayList<String> f = new ArrayList<String>(l);
ArrayList<String> f = new ArrayList<String>();
f.addAll(l);
方法:
方法 | 含义 | |
---|---|---|
add(元素) | 尾部添加元素 | boolean |
add(下标,元素) | 在下标之前插入元素 | void |
size() | 集合大小 | int |
get(下标) | 根据下标获取对应元素 | |
remove(下标) | 根据下标删除元素 | |
remove(元素) | 直接删除元素 | |
clear() | 清空集合 | |
set(下标,元素) | 修改对应下标的元素 | |
indexOf() lastIndexOf() | 集合元素的查找 |
测试1:
public class TestList {
public static void main(String[] args) {
//创建对象集合
ArrayList<Object> list = new ArrayList<Object>();
//添加
list.add(10);//默认装箱
list.add("ys");
list.add(10);
list.add(10.5);
//插入
//list.add(1, "nao");
//覆盖toString()
//System.out.println(list);
//集合大小
//System.out.println(list.size());
//System.out.println(list.get(0));
//越界异常
//System.out.println(list.get(list.size()));
//查询
for (int i = 0; i < list.size(); i++) {
if(list.get(i).equals("ys")) {
System.out.println("有");
}
}
}
}
测试2:
public class TestList2 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(10);//自动装箱Integer
list.add(3);
//删除
//list.remove(new Integer(10));//手动装箱
//list.clear();
//修改
list.set(1, 88);
System.out.println(list);
}
}
练习:
字符串集合,5个水果 存储集合(草莓, 葡萄,柚子,橘子,柠檬)
* 控制台接收一个水果
* 判断是否存在水果
* 存在,删除该水果
*不存在,将最后一个水果改为你需要的
public class TestList3 {
public static void main(String[] args) {
ArrayList<String> fruits = new ArrayList<String>();
fruits.add("草莓");
fruits.add("葡萄");
fruits.add("柚子");
fruits.add("橘子");
fruits.add("柠檬");
Scanner sc = new Scanner(System.in);
System.out.println("请输入水果名:");
String name = sc.next();
// int index = fruits.indexOf(name);
// if (index != -1) {
// fruits.remove(index);
//
// } else {
// fruits.set(fruits.size() - 1, name);
// }
boolean flag = true;
for (int i = 0; i < fruits.size(); i++) {
if(fruits.get(i).equals(name)) {
flag = false;
fruits.remove(i);
break;
}
}
if(flag) {
fruits.set(fruits.size() - 1, name);
}
System.out.println(fruits);
}
}
遍历:
ArrayList<String> fruits = new ArrayList<String>();
fruits.add("草莓");
fruits.add("葡萄");
fruits.add("柚子");
fruits.add("橘子");
fruits.add("柠檬");
System.out.println(fruits);
for (int i = 0; i < fruits.size(); i++) {
System.out.println(fruits.get(i));
}
for (String f : fruits) {
System.out.println(f);
}