以下代码均使用IntelliJ IDEA 2024.1下运行,代码来源为学习java过程中所写代码。交流学习使用。
1-Java入门
1.1Hello
public class Hello {
/**
* 主函数执行程序的入口点
* 此函数没有接收任何参数,也没有返回值
* 它首先打印多次"Hello",然后调用getCode()方法并打印其返回值
* @param args 命令行参数,本程序中未使用
*/
public static void main(String[] args) {
// 打印"Hello"十次
for (int i = 0; i < 10; i++) {
System.out.println("Hello");
}
// 调用getCode()方法并打印返回的结果
System.out.println(getCode());
}
//定义一个方法,生成6位验证码,并返回
public static String getCode() {
String code = "";
for (int i = 0; i < 6; i++) {
int num = (int) (Math.random() * 10);
code += num;
}
return code;
}
}
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
System.out.println("--------------------------------");
printHelloWorld();
System.out.println("--------------------------------");
System.out.println(sum(1, 2));
}
// 打印3行HelloWorld
public static void printHelloWorld() {
System.out.println("Hello World!");
System.out.println("Hello World!");
System.out.println("Hello World!");
}
// 我要求任意两个整数的和
public static int sum(int a, int b) {
return a + b;
}
}
1.2常见字面量的书写格式。
/**
* 目标:掌握常见字面量的书写格式。
*/
public class LiteralDemo {
public static void main(String[] args) {
printLiteral();
}
public static void printLiteral() {
// 请帮我直接输出常见的字面量
// 1、整型字面量,直接写
System.out.println(1);
// 2、浮点型字面量,直接写(小数)
System.out.println(1.0);
// 3、布尔型字面量,只有true false
System.out.println(true);
System.out.println(false);
// 4、字符型字面量,用单引号括起来,里面有且仅有一个字符
System.out.println('a');
System.out.println('磊');
// System.out.println('徐磊'); // 报错
System.out.println(' ');
// System.out.println('');// 报错
// 掌握一些特殊的字符:\n(换行功能) \t(Tab缩进功能)
System.out.println("hello\nWorld");
System.out.println("hello\tWorld");
// 5、字符串字面量,用双引号括起来,里面可以有任意字符
System.out.println("aaa");
System.out.println("");
System.out.println(" afsfa");
System.out.println("我爱你中国666abc");
}
}
1.3注释
/**
* 3、文档注释
* 这是一个程序
* 是用来讲解注释的使用的
*/
public class CommentDemo {
/**
* 这是一个main方法,是程序的入口
* 必须有这个main方法,程序才能执行
*/
public static void main(String[] args) {
// 目标:认识三种注释的写法。
// 1、单行注释:
// 打印2行诗句
System.out.println("我欲乘风归去,又恐琼楼玉宇");
/*
2、多行注释
打印3行诗句,依次打印
*/
System.out.println("我欲乘风归去,又恐琼楼玉宇");
System.out.println("我欲乘风归去,又恐琼楼玉宇");
System.out.println("我欲乘风归去,又恐琼楼玉宇");
}
}
1.4变量
public class VariableDemo1 {
public static void main(String[] args) {
// 目标:认识变量。
printVariable();
}
// 定义一个方法,来学习变量的定义
public static void printVariable() {
// 定义变量: 数据类型 变量名称 = 初始值;
int age = 18;
System.out.println(age);
// 定义一个小数变量,存储一个学生的Java成绩
double score = 90.5;
System.out.println(score);
System.out.println("======================");
// 为什么要用变量记住数据呢? 可以提高处理数据的灵活性和维护性。
int number = 32;
System.out.println(number);
System.out.println(number);
System.out.println(number);
System.out.println(number);
System.out.println(number);
System.out.println(number);
System.out.println("======================");
// 研究变量的特点:变量里的数据是可以被替换的
int age2 = 18;
age2 = 19; // 赋值 (从右边往左边看)
System.out.println(age2); // 19
age2 = age2 + 1; // 赋值 (从右边往左边看)
System.out.println(age2); // 20
System.out.println("======================");
// 需求:微信钱包目前有9.9,发出去了5元,又收到了6元,请实时输出钱包金额。
double money = 9.9;
System.out.println(money);
// 发出去了5元
money = money - 5; // 赋值 (从右边往左边看)
System.out.println(money);
// 又收到了6元
money = money + 6;
System.out.println(money);
System.out.println("======================");
char ch = 'A'; // 65的二进制。
System.out.println(ch + 1); // 66
char ch2 = 'a'; // 97的二进制。
System.out.println(ch2 + 1); // 98
System.out.println("======================");
// 程序中可以直接写进制数据
int i1 = 0B01100001; // 二进制 必须以0B 开头
System.out.println(i1);
int i2 = 0141; // 八进制 必须以0开头
System.out.println(i2);
int i3 = 0XFA; // 十六进制 必须以0X开头
System.out.println(i3);
}
}
public class VariableDemo2 {
public static void main(String[] args) {
// 目标:掌握8种基本数据类型定义变量。
printVariable();
}
// 请帮我设计一个方法,打印出8种基本数据类型定义的变量。
public static void printVariable() {
// 1. 整型
byte b = 10;
// byte b2 = 128; // 越界了,报错
short s = 20;
int i2 = 30;
// 注意:随便写一个整数字面量默认是int类型的,334254235555这个数据虽然没有超过long的范围,但是超过了int的范围,所以报错
// 如果希望334254235555这个是long类型,需要显示的指定,加上L或者l
long l1 = 334254235555L;
long l = 40;
// 2. 浮点型
// 注意:随便写一个浮点数字面量默认是double类型的,如果希望1.1是float类型的,必须加上f或者F
// float f2 = 1.1;
float f = 1.1f;
double d = 2.2;
// 3. 字符型
char c = 'a';
// 4. 布尔型
boolean flag = true;
boolean flag2 = false;
// 5. 字符串型(引用数据类型,后面再讲): 定义字符串变量记住字符串数据的
String str = "hello";
System.out.println(str);
}
}
2-Java基础语法
2.1基础方法
public class MethodDemo1 {
public static void main(String[] args) {
// 目标:掌握方法的定义和调用。
int sum = getSum(10, 20);
System.out.println("和是:" + sum);
System.out.println("----------------------------");
int sum2 = getSum(100, 200);
System.out.println("和是:" + sum2);
printHelloWorld();
System.out.println("----------------------------");
System.out.println(getCode(4));
System.out.println(getCode(5));
}
// 定义一个方法,求任意两个整数的和并返回
public static int getSum(int a, int b) {
return a + b;
}
public static double GetSum(int a,int b){
return a+b;
}
// 需求:打印3行HelloWorld,不需要参数,也不需要返回值
// 注意:如果方法没有返回结果,返回值类型必须声明成void.
// 无参数,无返回值类型
public static void printHelloWorld() {
System.out.println("HelloWorld");
System.out.println("HelloWorld");
System.out.println("HelloWorld");
}
// 需求3:获取一个指定位数的验证码返回。
// 掌握方法的定义格式:
// 需要接收数据吗? 需要,需要接收位数。 int len
// 需求返回数据吗? 需要,返回验证码。 String
// 有参数有返回值的方法
public static String getCode(int len) {
String code = "";
for (int i = 0; i < len; i++) {
int num = (int) (Math.random() * 10);
code += num;
}
return code;
}
}
public class MethodDemo2 {
public static void main(String[] args) {
// 目标:认识方法重载。
fire(100, 200);
}
// 定义一个方法,打印一个整数
public static void print(int a) {
System.out.println(a);
}
// 定义一个重载的方法
public static void print(String str) {
System.out.println(str);
}
// 定义一个重载的方法
public static void print(double d, int a) {
System.out.println(d);
}
public static void print(int a, double d) {
System.out.println(d);
}
// 重复的方法,冲突了!
// public static void print(int a1, double d1) {
// System.out.println(d1);
// }
// 注意:方法重载只关心方法名称相同,形参列表不同(类型不同,个数不同, 顺序不同),其他都无所谓、
// 需求:发射导弹
public static void fire(int x, int y) {
System.out.println("发射导弹,坐标:" + x + "," + y);
}
// 定义一个重载方法
public static void fire(double x, double y, String location) {
System.out.println("发射导弹,坐标:" + x + "," + y);
}
}
public class MethodDemo3 {
public static void main(String[] args) {
// 目标:掌握在无返回值的方法中单独使用 return; :提前结束方法。
div(10, 0);
}
// 设计一个除法的功能。
public static void div(int a, int b) {
if (b == 0) {
System.out.println("除数不能为0");
return; // 提前结束方法。 卫语言风格!!
}
System.out.println(a / b);
}
}
2.2数据类型转换
public class TypeDemo1 {
public static void main(String[] args) {
// 目标:认识自动类型转换,强制类型转换。
byte a = 12;
print(a); // 自动类型转换
print2(a); // 自动类型转换
System.out.println("=====================");
int i = 20;
// print3(i); // 类型范围大的变量不能直接赋值给类型范围小的变量,会报错的!!
// 强制类型转换。 类型 变量2 = (类型)变量1;
byte j = (byte) i; // 强制类型转换
print3(j);
System.out.println("=====================");
int m = 1500;
byte n = (byte) m;
System.out.println(m);
System.out.println(n); // 出现数据溢出!!
System.out.println("=====================");
double k = 3.14;
int l = (int) k; // 浮点型转换成整数,直接去掉小数部分
System.out.println(l); // 3
}
public static void print(int b) {
System.out.println(b);
}
public static void print2(double c) {
System.out.println(c);
}
public static void print3(byte j) {
System.out.println(j);
}
}
public class TypeDemo2 {
public static void main(String[] args) {
// 目标:理解表达式的自动类型提升。
int result = calc2((byte) 110, (byte) 120);
System.out.println(result);
int result2 = calc3((byte) 110, (byte) 120);
System.out.println(result2);
}
// 需求:接收各种类型的数据运算。
public static double calc(int a, int b, double c, char r) {
// 表达式的最终结果类型是有最高类型决定的
return a + b + c + r;
}
public static int calc2(byte a, byte b) {
// byte short char运算时会直接提升成int运算。
return a + b;
}
public static byte calc3(byte a, byte b) {
byte c = (byte) (a + b);
return c;
}
}
2.3输入输出
// 1. 导包: 告诉我们自己的程序,去JDK哪里找Scanner程序用
import org.w3c.dom.ls.LSOutput;
import java.util.Scanner;
//public class ScannerDemo1 {
// public static void main(String[] args) {
// printUserInfo();
// }
//
// // 需求:我是一个零基础小白,请帮我写一个程序,可以让用户键盘输入用户名和年龄,然后打印出来
// public static void printUserInfo() {
// // 2. 创建对象(抄写这一行代码,得到一个Scanner扫描器对象)
// Scanner sc = new Scanner(System.in);
//
// // 3. 获取用户输入
// System.out.println("请输入用户名:");
// // 让程序在这一行暂停,等到用户输入一个字符串名称,直到按了回车键之后,把名字交给变量username记住再往下走
// String username = sc.next();
// System.out.println("您叫:" + username);
//
// System.out.println("请输入年龄:");
// // 让程序在这一行暂停,等到用户输入一个整数,直到按了回车键之后,把年龄交给变量age记住再往下走
// int age = sc.nextInt();
// System.out.println("您多少岁:" + age);
// }
//}
public class ScannerDemo1 {
public static void main(String[] args) {
printUserInfo();
}
private static void printUserInfo() {
Scanner sc=new Scanner(System.in);
System.out.println("请输入用户名:");
String name=sc.next();
System.out.println("你的名字是:"+name);
System.out.println("输入年龄");
int age=sc.nextInt();
System.out.println("你的年龄是:"+age);
System.out.println("请输入你的体重");
double weight=sc.nextDouble();
System.out.println("你的体重是:"+weight);
System.out.println("请输入你的性别");
char sex=sc.next().charAt(0);
System.out.println("你的性别是:"+sex);
System.out.println("请输入你的身高");
float height=sc.nextFloat();
System.out.println("你的身高是:"+height);
System.out.println("请输入你的生日");
String birthday=sc.next();
System.out.println("你的生日是:"+birthday);
System.out.println("请输入你的地址");
String address=sc.next();
System.out.println("你的地址是:"+address);
}
}
2.4运算符
public class OperatorDemo1 {
public static void main(String[] args) {
// 目标:搞清楚基本的算术运算符。
// print(10, 2);
print(10, 3);
System.out.println("---------------------------------");
print2();
}
public static void print(int a, int b) {
System.out.println(a + b);
System.out.println(a - b);
System.out.println(a * b);
System.out.println(a / b); // 3.3333... ==> 3
System.out.println((double) a / b);
System.out.println(1.0 * a / b);
System.out.println(a % b);
}
// 需求:研究+符号做连接符还是做运算符.
public static void print2() {
int a = 5;
System.out.println("abc" + a); // abc5
System.out.println(a + 5); // 10
System.out.println("itheima" + a + 'a'); // itheima5a
System.out.println(a + 'a' + "itheima"); // 102itheima
}
}
public class OperatorDemo2 {
public static void main(String[] args) {
// 目标:理解自增自减运算符
print(10);
System.out.println("=========================");
print2(10);
}
// 设计一个方法,接收一个整数。
public static void print(int a) {
a++; // a = a + 1;
++a;
System.out.println(a);
a--;
--a;
System.out.println(a);
}
// 设计一个方法,理解自增和自减放在变量前后的区别
public static void print2(int a) {
int b = a++; // 先用后加
System.out.println(a); // 11
System.out.println(b); // 10
int c = ++a; // 先加后用
System.out.println(a); // 12
System.out.println(c); // 12
}
}
public class OperatorDemo3 {
public static void main(String[] args) {
// 目标:掌握扩展的赋值运算符。
receive(5);
print();
}
// 需求:收红包。
public static void receive(int b) {
// 拿到自己钱包的金额。
int a = 100;
a += b; // 等价于 a = (a的类型)(a + b);
System.out.println("收红包后,我的钱包金额:" + a);
byte a1 = 10;
byte a2 = 20;
a1 += a2; // 等价于 a1 = (byte) (a1 + a2); 扩展赋值运算符自带强制类型转换。
System.out.println(a1);
}
// 需求:帮我再演示一下其他几个扩展的赋值运算符。
public static void print() {
int a = 10;
a -= 5; // 等价于 a = (a的类型)(a - 5);
System.out.println(a); // 5
int b = 10;
b *= 5; // 等价于 b = (b的类型)(b * 5);
System.out.println(b); // 50
int c = 10;
c /= 5; // 等价于 c = (c的类型)(c / 5);
System.out.println(c); // 2
int d = 10;
d %= 5; // 等价于 d = (d的类型)(d % 5);
System.out.println(d); // 0
}
}
public class OperatorDemo4 {
public static void main(String[] args) {
// 目标:理解关系运算符。
print(10, 2);
print2(10, 10);
}
public static void print(int a, int b) {
System.out.println(a > b); // true
System.out.println(a < b); // false
System.out.println(a >= b); // true 要么大于要么等于
System.out.println(a <= b); // false 要么小于要么等于
System.out.println(a == b); // false
System.out.println(a != b); // true
}
public static void print2(int a, int b) {
System.out.println(a > b); // false
System.out.println(a < b); // false
System.out.println(a >= b); // true
System.out.println(a <= b); // true
System.out.println(a == b); // true
System.out.println(a != b); // false
}
}
public class OperatorDemo5 {
public static void main(String[] args) {
// 目标:三元运算符。
print(10, 40);
print(59);
System.out.println("较大值:" + getMax(10, 20, 30));
System.out.println("较大值:" + getMax2(10, 20, 30));
}
public static void print(int a, int b) {
int max = a > b ? a : b;
System.out.println("较大值:" + max);
}
// 需求:判断成绩是否通过或者挂科
public static void print(int score) {
String result = score >= 60 ? "通过" : "挂科";
System.out.println(result);
}
// 需求:求三个整数的较大值返回。
public static int getMax(int a, int b, int c) {
int max = a > b ? a : b;
max = max > c ? max : c;
return max;
}
public static int getMax2(int a, int b, int c) {
// 三元运算符的嵌套
int max = a > b ? (a > c ? a : c) : (b > c ? b : c);
return max;
}
}
public class OperatorDemo6 {
public static void main(String[] args) {
// 目标:掌握逻辑运算符的使用。
System.out.println(isMatch(180, 70, '女')); // true
System.out.println(isMatch(180, 70, '男')); // false
System.out.println(isMatch2(180, 10000));
System.out.println(isMatch2(160, 1000000));
System.out.println(isMatch2(160, 100)); // false
isMatch3(true);
System.out.println("-----------------------------");
isMatch4();
System.out.println("-------------------------------");
print();
}
// 需求:判断某个人的条件是否满足择偶要求,如果满足返回true.否则是false
// 条件是:身高高于170,体重在60-80之间,且性别为女。
// & 必须前后条件都是true结果才是true,只要有一个是false,结果一定是false
public static boolean isMatch(int height, int weight, char sex) {
boolean result = height > 170 & weight >= 60 & weight <= 80 & sex == '女';
return result;
}
// 需求:找一个男朋友,要求是要么身高高于180,要么收入高于30万。
// | 只要前后条件有一个为true,结果一定是true,必须都是false结果才是false
public static boolean isMatch2(int height, int income) {
boolean result = height >= 180 | income > 300000;
return result;
}
// ! 非,你真我假,你假我真
public static void isMatch3(boolean flag) {
System.out.println(!flag);
}
// ^ 异或,相同条件结果为false,条件不同为true.
public static void isMatch4() {
System.out.println(false ^ false); // false
System.out.println(true ^ true); // false
System.out.println(true ^ false); // true
System.out.println(false ^ true); // true
}
// 判断&& || 与 & |的区别
public static void print() {
int a = 111;
int b = 2;
// System.out.println(a > 1000 && ++b > 1); // false && 发现左边条件为false右边直接不执行
System.out.println(a > 1000 & ++b > 1); // false & 即便发现左边条件为false右边依然执行
System.out.println(b); // 3
int i = 10;
int j = 20;
// System.out.println(i > 6 || ++j > 1); // true || 发现左边条件为true右边直接不执行
System.out.println(i > 6 | ++j > 1); // true & 即便发现左边条件为true右边依然执行
System.out.println(j);
}
}
2.5实战案例
import java.util.Scanner;
public class AllTest {
public static void main(String[] args) {
// 目标:完成健康计算器。
Scanner sc = new Scanner(System.in);
// 1、先让用户输入自己的个人信息:身高、体重、性别、年龄
System.out.println("请您输入您的身高(米):");
double height = sc.nextDouble();
System.out.println("请您输入您的体重(千克):");
double weight = sc.nextDouble();
System.out.println("请您输入您的性别(男/女):");
String sex = sc.next(); // "男"
System.out.println("请您输入您的年龄:");
int age = sc.nextInt();
double bmi = calcBMI(height, weight);
System.out.println("您的bmi值是:" + bmi);
// 判断用户的bmi值的情况。。。
double bmr = calcBMR(height, weight, sex, age);
System.out.println("您的bmr值是:" + bmr);
// 判断bmr的情况。。。
}
// 2、根据个人信息,计算BMI指数(把数据交给一个独立的方法来计算并返回这个结果)
public static double calcBMI(double height, double weight) {
return weight / (height * height);
}
// 3、根据个人信息,计算BMR指数(把数据交给一个独立的方法来计算并返回这个结果)
public static double calcBMR(double height, double weight, String sex, int age) {
double bmr = 0;
if ("男".equals(sex)) {
bmr = 88.362 + (13.397 * weight + 4.799 * height - 5.677 * age) ;
} else {
bmr = 447.593 + (9.247 * weight + 3.098 * height - 4.330 * age);
}
return bmr;
}
}
3-程序流程控制
3.1-if
import java.util.Scanner;
public class IfDemo1 {
public static void main(String[] args) {
// 目标:认识if语句,搞清楚其写法和应用场景。 (独立功能独立成方法)
test1();
test2();
test3();
}
public static void test1(){
int age = 10;
if(age > 18){
System.out.println("可以上网");
}
System.out.println("洗洗睡吧!");
// 注意:if语句中如果只有一行代码,大括号可以省略不写
}
public static void test2(){
// 需求: 假如您的钱包金额是90元,现在要转出去80元,请用if分支实现
// 要求:钱够就提示转账成功,钱不够提示余额不足
int money = 10;
if(money >= 80){
System.out.println("转账成功");
}else{
System.out.println("余额不足");
}
}
public static void test3(){
// 需求:有个绩效系统,每个月由主管给员工打分,
// 会输出你这个月的绩效级别:A+ A B C D
// 级别的区间情况: A+ 90-100 A 80-90 B 70-80 C 60-70 D 0-60
System.out.println("请您录入该员工的分数:");
Scanner sc = new Scanner(System.in);
int score = sc.nextInt();
if(score >= 90 && score <= 100){
System.out.println("A+");
}else if(score >= 80 && score < 90){
System.out.println("A");
}else if(score >= 70 && score < 80){
System.out.println("B");
}else if(score >= 60 && score < 70){
System.out.println("C");
}else if(score >= 0 && score < 60){
System.out.println("D");
}else {
System.out.println("分数输入有误");
}
}
}
public class IfTest2 {
public static void main(String[] args) {
// 目标:完成自动汽车驾驶程序的书写:以便可以根据红绿灯状态正确形式。
test1();
}
public static void test1() {
// 1、假设现在通过摄像头获取到了三种灯的状态信息如下
boolean red = false;
boolean yellow = false;
boolean green = false;
// 2、使用if语句判断红灯亮,则停止,黄灯亮,则准备,绿灯亮,则开始,否则停止。
if (red) {
System.out.println("红灯亮,停止!");
} else if (yellow) {
System.out.println("黄灯亮,准备!");
} else if (green) {
System.out.println("绿灯亮,开始!");
} else {
System.out.println("灯泡故障,停止!");
}
}
}
3.2-switch
import java.util.Scanner;
public class SwitchDemo3 {
public static void main(String[] args) {
// 目标:搞清楚switch分支结构的应用和写法,理解其执行流程。
test1();
}
// 需求:根据男女性别的不同,推荐不同的书本信息给其观看。
public static void test1() {
// 1、让用户输入选择自己的性别。
System.out.println("请输入您的性别:");
Scanner sc = new Scanner(System.in);
String sex = sc.next(); // "男" "女" "其他的"
// 2、根据用户输入的性别这个值,判断该做什么
switch (sex) {
case "男":
System.out.println("推荐《Java从入门到精通》");
break;
case "女":
System.out.println("推荐《从您的全世界路过》");
break;
default:
System.out.println("你不是人,没有东西推荐!");
}
}
}
public class SwitchDemo4 {
public static void main(String[] args) {
// 目标:搞清楚switch的注意事项,穿透性的应用。
test1();
test3();
}
// 1、表达式类型只能是byte、short、int、char,JDK5开始支持枚举,JDK7开始支持String、不支持double、float、long。
public static void test1() {
// double a = 0.1 + 0.2;
// switch (a) {
// case 0.3:
// System.out.println("10.5");
// break;
// case 10.8:
// System.out.println("10");
// break;
// default:
// System.out.println("default");
// }
}
// 2、case给出的值不允许重复,且只能是字面量,不能是变量。
public static void test2() {
int a = 10;
int b = 15;
switch (a) {
case 10:
System.out.println("10");
break;
case 15:
System.out.println("10");
break;
default:
System.out.println("default");
}
}
// 3、正常使用switch的时候,不要忘记写break,否则会出现穿透现象。
// 穿透性的作用:想通程序的case块,可以通过穿透性进行合并,从而减少重复代码的书写。
// 周一:埋头苦干,解决bug 周五:自己整理代码
// 周二:请求大牛程序员帮忙 周六:打游戏
// 周三:请求大牛程序员帮忙 周日:打游戏
// 周四:请求大牛程序员帮忙
public static void test3() {
String week = "周六";
switch (week) {
case "周一":
System.out.println("埋头苦干,解决bug");
break;
case "周二":
case "周三":
case "周四":
System.out.println("请求大牛程序员帮忙");
break;
case "周五":
System.out.println("自己整理代码");
break;
case "周六":
case "周日":
System.out.println("打游戏");
break;
default:
System.out.println("星期信息有误!");
}
}
}
3.3-for
public class ForDemo1 {
public static void main(String[] args) {
// 目标:掌握for循环的书写,搞清楚其执行流程。
test1();
}
public static void test1() {
// 需求:使用for循环,打印3行HelloWorld
/**
* 计算机先遇到for知道要开启循环,然后立即执行int i = 0
* 接着判断循环条件 0 < 3,成立,执行循环体输出第一行HelloWorld,然后执行i++,i = 1
* 接着判断循环条件 1 < 3,成立,执行循环体输出第二行HelloWorld,然后执行i++,i = 2
* 接着判断循环条件 2 < 3,成立,执行循环体输出第三行HelloWorld,然后执行i++,i = 3
* 接着判断循环条件 3 < 3,不成立,循环结束。
*/
for (int i = 0; i < 3; i++) {
System.out.println("HelloWorld");
}
// System.out.println(i); // 报错
System.out.println("=======================");
for (int i = 1; i < 6; i++) {
// i = 1、2、3、4、5
System.out.println("HelloWorld");
}
System.out.println("=======================");
for (int i = 1; i <= 9; i+=2) {
// i = 1 3 5 7 9
System.out.println("HelloWorld");
}
}
}
public class ForTest2 {
public static void main(String[] args) {
// 目标:完成for循环求和的案例。
System.out.println("1到5的和是:" + sum(100));
}
public static int sum(int n){
// 1、初始化一个变量:首先,你需要一个变量来存储累加和,初始值设为0。
int sum = 0;
// 2、循环结构:因为你要计算1到5的和,所以需要一个循环结构来依次处理这些数字。最简单的是使用for循环,从1遍历到5
for (int i = 1; i <= n; i++) {
// i = 1 2 3 4 5
// 3、累加操作:在每次循环中,将当前数字加到累加变量上
sum += i;
}
// 4、返回结果:循环结束后,返回累加变量的值,即为1到5的和。
return sum;
}
}
public class ForTest3 {
public static void main(String[] args) {
// 目标:求奇数和。
System.out.println("1-10的奇数和是:" + sum(10));
System.out.println("1-10的奇数和是:" + sum2(10));
}
public static int sum(int n) {
// 1、定义变量累加奇数
int sum = 0;
// 2、循环1-n的全部数字。
for (int i = 1; i <= n; i++) {
// i = 1 2 3 4 5 6 7 8 9 10
// 3、判断当前数字是否是奇数
if (i % 2 == 1) {
// 4、如果是奇数,累加到sum中
sum += i;
}
}
// 5、返回累加结果
return sum;
}
public static int sum2(int n) {
// 1、定义变量累加奇数
int sum = 0;
// 2、循环1-n的全部数字。
for (int i = 1; i <= n; i += 2) {
// i = 1 3 5 7 9
// 3、累加到sum中
sum += i;
}
// 5、返回累加结果
return sum;
}
}
public class DeadForDemo7 {
public static void main(String[] args) {
// 目标:掌握死循环的写法。
test();
}
public static void test(){
// 1、for循环实现死循环
// for ( ; ; ) {
// System.out.println("Hello World1!");
// }
// 2、while循环实现死循环(经典写法)
// while (true) {
// System.out.println("Hello World2!");
// }
// 3、do...while循环实现死循环
do {
System.out.println("Hello World3!");
}while (true);
}
}
public class ForForDemo8 {
public static void main(String[] args) {
// 目标:搞清楚循环嵌套的流程。
test();
print99();
}
public static void test(){
// 需求:打印4行5列星星。
// 1、定义一个循环控制打印几行。
for (int i = 1; i <= 10; i++) {
// 2、定义一个循环控制每行打印多少个星星
for (int j = 1; j <= 10; j++) {
System.out.print("*"); // 不换行打印
}
// 3、打印完一行需要换行
System.out.println(); // 换行
}
}
// 定义一个方法
public static void print99(){
// 1、定义一个循环控制打印多少行
for (int i = 1; i <= 9; i++) {
// i = 1 2 3 4 5 6 7 8 9
// 2、定义一个循环控制当前行的列信息。
for (int j = 1; j <= i; j++) {
// 3、打印每列的信息。
System.out.print(j + " x " + i + " = " + (j * i) + "\t");
}
// 3、换行
System.out.println();
}
}
}
3.4-while
public class WhileDemo4 {
public static void main(String[] args) {
// 目标:认识while循环的写法,搞清楚其执行流程。
test1();
}
public static void test1() {
int i = 0;
while (i < 3) {
System.out.println("Hello World!");
i++;
}
System.out.println(i); // 3
}
}
public class WhileTest5 {
public static void main(String[] args) {
// 目标:完成while循环的需求:复利计算。
System.out.println("需要多少年:" + calc());
System.out.println("需要折叠多少次:" + calc2());
}
// 复利计算:我们本金是10万,复利是1.7%,请问多少年后本金翻倍。
public static int calc() {
// 1、定义变量记录程序需要的处理数据。
double money = 100000;
double rate = 0.017;
int year = 0; // 要存多少年的意思。
// 2、控制循环,只要发现本金还是小于目标金额200000时,就需要继续存一年。
while ( money < 200000 ){
year++;
// 金额要计算一下。
money = money * (1 + rate);
System.out.println("第" +year+"年有多少钱:" + money);
}
return year;
}
// 需求:珠穆朗玛峰高度是8848860,纸张厚度是0.1,折叠多少次可以达到山峰高度。
public static int calc2() {
// 1、把数据拿到程序中来。
double height = 8848860;
double thickness = 0.001;
int count = 0;
// 2、控制循环,只要纸张厚度还没有达到珠穆朗玛峰高度,就需要继续折叠。
while (thickness < height) {
// 3、计算折叠次数。
count++;
// 4、计算纸张厚度。
thickness *= 2; // thickness = thickness * 2;
}
// 5、返回折叠次数。
return count;
}
}
3.5-do while
public class DoWhileDemo6 {
public static void main(String[] args) {
// 目标:搞清楚do-while循环的写法,并理解其特点。
test1();
}
// 使用do-while循环控制打印三行HelloWorld
public static void test1() {
// 特点:先执行后判断(一定会执行一次)。
int i = 0;
do {
System.out.println("HelloWorld");
i++;
} while (i < 3);
}
}
3.6-break/continue
public class BreakAndContinueDemo9 {
public static void main(String[] args) {
// 目标:搞清楚break和continue的作用。
test1();
System.out.println("------------------");
test2();
}
public static void test1() {
for (int i = 0; i < 10; i++) {
if (i == 5) {
break; // 跳出并结束循环
}
System.out.println(i);
}
}
public static void test2() {
for (int i = 0; i < 10; i++) {
if (i == 5) {
continue; // 跳出本次循环,继续下一次循环
}
System.out.println(i);
}
}
}
3.7实战案例
import java.util.Scanner;
public class Test1 {
public static void main(String[] args) {
// 目标:简易版计算器开发。
// 1、键盘录入两个整数,以及运算符。
Scanner sc = new Scanner(System.in);
System.out.println("请输入第一个数字:");
double num1 = sc.nextDouble();
System.out.println("请输入第二个数字:");
double num2 = sc.nextDouble();
System.out.println("请输入运算符(+, -, *, /):");
String operator = sc.next(); // "+"
// 2、把这个数据交给一个独立的计算方法,帮我计算结果并返回给我。
double result = calc(num1, num2, operator);
System.out.println("计算结果是:" + result);
}
public static double calc(double num1, double num2, String operator) {
double result = 0; // 定义一个double类型的变量记录本次运算的结果,方便返回!!
switch (operator) {
case "+":
result = num1 + num2;
break;
case "-":
result = num1 - num2;
break;
case "*":
result = num1 * num2;
break;
case "/":
result = num1 / num2;
break;
default:
System.out.println("运算符有误,请重新输入");
}
return result;
}
}
import java.util.Random;
import java.util.Scanner;
public class Test2 {
public static void main(String[] args) {
// 目标:猜数字游戏
guess();
}
public static void guess() {
// 1、生成随机数: 1-100之间
// 方式一:
// Math.random()返回[0,1)的随机小数
// (int)Math.random() * 100 ==> [0, 100)的整数 => [0,99] + 1 => [1,100]
// int num = (int)(Math.random() * 100) + 1;
// 方式二
Random r = new Random(); // 得到一个随机数对象.
int luckNumber = r.nextInt(100) + 1; // [0, 99] + 1 => [1, 100]
// 2、定义一个死循环让用户一直猜测,直到猜中才结束循环。
Scanner sc = new Scanner(System.in);
while (true) {
// 3、让用户输入猜测的数字
System.out.println("请输入猜测的数字:");
int guessNumber = sc.nextInt();
// 4、判断猜测的数字和随机数是否一致
if (guessNumber == luckNumber) {
System.out.println("恭喜你,猜对了!");
break;
} else if (guessNumber > luckNumber) {
System.out.println("猜大了!");
} else {
System.out.println("猜小了!");
}
}
}
}
public class Test3 {
public static void main(String[] args) {
// 目标:开发验证码。
// 1、调用一个方法返回执行位数的验证码,每位只能是数字或者大写字母或者小写字母
System.out.println(getCode(4));
System.out.println(getCode(6));
}
public static String getCode(int n) {
// 2、定义一个字符串变量用于记录生产的验证码。
String code = "";
// 3、循环n次,每次生成一个验证码。
for (int i = 0; i < n; i++) {
// i = 0 1 2 3
// 4、为当前位置随机生成一个数字或者大写字母或者小写字母。 数字0 / 大写1 / 小写2
// 随机一个 0 或者 1 或者 2 表示当前位置随机的字符类型。
int type = (int) (Math.random() * 3); // [0,1) *3 => 0 1 2
// 5、使用switch判断当前位置随机的字符类型
switch (type) {
case 0:
// 6、如果当前位置是数字,则随机生成一个数字0-9,然后拼接。
int num = (int) (Math.random() * 10);
code += num;
break;
case 1:
// 7、如果当前位置是大写字母,则随机生成一个字母A-Z,然后拼接。 'A' 65 'Z' 65+25
int num1 = (int) (Math.random() * 26); // [0,25]
char ch = (char) (65 + num1); // 得到大写字母的随机编号,转成大写字母
code += ch;
break;
case 2:
// 8、如果当前位置是小写字母,则随机生成一个字母a-z,然后拼接。 'a' 97 'z' 97+25
int num2 = (int) (Math.random() * 26); // [0,25]
char ch1 = (char) (97 + num2);
code += ch1;
break;
}
}
return code;
}
}
public class Test4 {
public static void main(String[] args) {
// 目标:找出101-200之间的全部素数。
int count = 0;
// 1、遍历101-200
for (int i = 101; i <= 200; i++) {
// i = 101 102 103 103 ... 200
// 2、每遍历到一个数字,判断这个数字是否是素数,是则输出。(独立功能独立成方法)
if (isPrime(i)) {
System.out.println(i);
count++;
}
}
System.out.println("素数的个数为:" + count);
}
public static boolean isPrime(int num) {
// num = 101
// 定义一个循环从2开始找到该数的一半,只要发现有一个数字能整数num这个数,num就不是素数
// 如果都没有找到,那么num就是素数
for (int i = 2; i <= num / 2; i++) {
// i = 2 3 4 5 ...
// 2、判断num是否能被i整除,能则返回false,不能则返回true
if (num % i == 0) {
return false;
}
}
return true; // 是素数。
}
}
4-面向对象
4.1面向对象编程
public class Star {
String name;
int age;
String gender;
double height;
double weight;
}
// 学生类
// 封装:把数据和对数据的处理放到同一个类中去
public class Student {
String name;
double chinese;
double math;
public void printAllScore(){
System.out.println(name + "的总成绩是:" +
(chinese + math));
}
public void printAverageScore(){
System.out.println(name + "的平均成绩是:" +
(chinese + math) / 2);
}
}
public class Test {
public static void main(String[] args) {
// 目标:学会创建对象.
// 创建对象的格式:类名 对象名 = new 类名();
Star s1 = new Star();
s1.name = "王祖贤";
s1.age = 50;
s1.gender = "女";
s1.height = 172.5;
s1.weight = 50.5;
System.out.println(s1.name);
System.out.println(s1.age);
System.out.println(s1.gender);
System.out.println(s1.height);
System.out.println(s1.weight);
// 创建对象,存储杨幂的数据
Star s2 = new Star();
s2.name = "杨幂";
s2.age = 38;
s2.gender = "女";
s2.height = 171.5;
s2.weight = 52.5;
System.out.println(s2.name);
System.out.println(s2.age);
System.out.println(s2.gender);
System.out.println(s2.height);
System.out.println(s2.weight);
}
}
public class Test2 {
public static void main(String[] args) {
// 目标:创建学生对象存储学生数据,并操作学生数据。
Student St1 = new Student();
St1.name = "播妞";
St1.chinese = 100;
St1.math = 100;
St1.printAllScore();
St1.printAverageScore();
System.out.println(St1);
Student s2 = new Student();
s2.name = "播仔";
s2.chinese = 50;
s2.math = 100;
s2.printAllScore();
s2.printAverageScore();
System.out.println(s2);
}
}
4.2构造器
public class Student {
String name;
int age;
char sex;
// 1、无参数构造器:
// 构造器:是一种特殊方法,不能写返回值类型,名称必须是类名,就是构造器。
public Student(){
System.out.println("=====无参数构造器执行了=======");
}
// 2、有参数构造器
public Student(String n){
System.out.println("=====有参数String n构造器执行了=======");
}
public Student(String name, int age, char sex){
this.name = name;
this.age = age;
this.sex = sex;
}
}
public class Test {
public static void main(String[] args) {
// 目标:认识类的构造器,搞清楚其特点和常见应用场景。
// 构造器的特点:创建对象时,对象会立即自动调用构造器。
Student s1 = new Student();
Student s2 = new Student("西门吹雪");
System.out.println("==============");
Student t1 = new Student();
t1.name = "石轩";
t1.age = 22;
t1.sex = '男';
System.out.println(t1.name);
System.out.println(t1.age);
System.out.println(t1.sex);
// 对象的一种常见应用场景:创建对象时可以立即为对象赋值
Student t2 = new Student("dlei", 18, '男');
System.out.println(t2.name);
System.out.println(t2.age);
System.out.println(t2.sex);
}
}
4.3-this
public class Student {
// 成员变量
String name;
public void print(){
// this是一个变量,用在方法中,用于拿到当前对象。
// 哪个对象调用这个方法,this就拿到哪个对象。
System.out.println(this);
System.out.println(this.name);
}
// 局部变量
public void printHobby(String name){
System.out.println(this.name + "喜欢" + name);
}
}
public class Test {
public static void main(String[] args) {
// 目标:认识this关键字,搞清楚this关键字的应用场景。
Student s1 = new Student();
s1.name = "张三";
s1.print();
System.out.println(s1);
System.out.println("==========================");
Student s2 = new Student();
s2.print();
System.out.println(s2);
System.out.println("==========================");
Student s3 = new Student();
s3.name = "汪苏泷";
s3.printHobby("唱歌!");
}
}
4.4关键字
public class Student {
String name;
// 1、如何隐藏:使用private关键字(私有,隐藏)修饰成员变量,就只能在本类中被直接访问,
// 其他任何地方不能直接访问。
private int age;
private double chinese;
private double math;
// 2、如何暴露(合理暴露):使用public修饰(公开)的get和set方法合理暴露
// 成员变量的取值和赋值。
public void setAge(int age){ // 为年龄赋值
if(age > 0 && age < 200){
this.age = age;
}else {
System.out.println("您赋值的年龄数据非法!");
}
}
public int getAge(){ // 获取年龄
return age;
}
public void setChinese(double chinese) {
this.chinese = chinese;
}
public double getChinese() {
return chinese;
}
public void printAllScore(){
System.out.println(name + "的总成绩是:" +
(chinese + math));
}
public void printAverageScore(){
System.out.println(name + "的平均成绩是:" +
(chinese + math) / 2);
}
}
public class Test {
public static void main(String[] args) {
// 目标:搞清楚封装的设计思想:合理隐藏合理暴露。
// 学会如何隐藏如何暴露。
Student s1 = new Student();
s1.setAge(19); // 赋值
System.out.println(s1.getAge()); // 取值
}
}
4.5封装
public class Student {
// 1、成员变量需要私有
private String name;
private int age;
private char sex;
private double math;
private double english;
// 3、必须提供无参构造器。有参数构造器可有可无的。
public Student() {
}
public Student(String name, int age, char sex, double math, double english) {
this.name = name;
this.age = age;
this.sex = sex;
this.math = math;
this.english = english;
}
// 2、必须提供getter和setter方法。
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public double getMath() {
return math;
}
public void setMath(double math) {
this.math = math;
}
public double getEnglish() {
return english;
}
public void setEnglish(double english) {
this.english = english;
}
}
/** 学生业务操作对象:负责对学生的数据进行业务处理 */
public class StudentOperator {
private Student s; // 记住要操作的学生对象。
public StudentOperator(Student s) {
this.s = s;
}
public void printAllScore() {
System.out.println(s.getName() + "总成绩是:" + (s.getMath() + s.getEnglish()));
}
public void printAverageScore() {
System.out.println(s.getName() + "平均成绩是:" + (s.getMath() + s.getEnglish()) / 2);
}
}
public class Test {
public static void main(String[] args) {
// 目标:认识实体类,搞清楚实体类的作用和应用场景。
// 实体类的基本作用:创建对象、封装数据。
// 1、通过无参数构造器初始化对象
Student s1 = new Student();
s1.setName("张三");
s1.setAge(18);
s1.setSex('男');
s1.setMath(50);
s1.setEnglish(100);
// 2、通过有参数构造器初始化对象
Student s2 = new Student("翠花", 20, '女', 60, 90);
// 3、创建学生操作对象,处理学生的数据
StudentOperator so = new StudentOperator(s1);
so.printAllScore(); // ALT + ENTER
so.printAverageScore();
}
}
4.6-static
public class Student {
// 静态变量:有static修饰,属于类,只加载一份,可以被类和类的全部对象共享访问
static String name;
// 实例变量:没有static修饰,属于对象,每个对象都有一份
int age;
}
public class User {
public static int count = 0;
public User(){
// User.count++;
// 注意:同一个类中访问静态成员可以省略类名不写
count++;
}
}
public class Test {
public static void main(String[] args) {
// 目标:认识static修饰成员变量,特点、访问机制,搞清楚作用。
// 1、类名.静态变量(推荐)
Student.name = "袁华";
System.out.println(Student.name);
// 2、对象名.静态变量(不推荐)
Student s1 = new Student();
s1.name = "马冬梅";
Student s2 = new Student();
s2.name = "秋雅";
System.out.println(s1.name); // 秋雅
System.out.println(Student.name); // 秋雅
// 3、对象名.实例变量
s1.age = 23;
s2.age = 18;
System.out.println(s1.age); // 23
// System.out.println(Student.age); // 报错!
}
}
public class Test2 {
public static void main(String[] args) {
// 目标:了解静态变量的应用。
new User();
new User();
new User();
new User();
System.out.println(User.count);
}
}
4.7-static(二)
public class Student {
private double score;
// 静态方法:有static修饰,属于类持有。
public static void printHelloWorld(){
System.out.println("Hello World");
System.out.println("Hello World");
System.out.println("Hello World");
}
// 实例方法:没有static修饰,属于对象持有。
public void printPass(){
System.out.println(score >= 60 ? "通过了" : "您挂科了!");
}
public void setScore(double score) {
this.score = score;
}
}
// 静态方法设计工具类。
public class VerifyCodeUtil {
// 工具类没有创建对象的必要性,所以建议私有化构造器
private VerifyCodeUtil() {}
public static String getCode(int n) {
// 2、定义一个字符串变量用于记录生产的验证码。
String code = "";
// 3、循环n次,每次生成一个验证码。
for (int i = 0; i < n; i++) {
// i = 0 1 2 3
// 4、为当前位置随机生成一个数字或者大写字母或者小写字母。 数字0 / 大写1 / 小写2
// 随机一个 0 或者 1 或者 2 表示当前位置随机的字符类型。
int type = (int) (Math.random() * 3); // [0,1) *3 => 0 1 2
// 5、使用switch判断当前位置随机的字符类型
switch (type) {
case 0:
// 6、如果当前位置是数字,则随机生成一个数字0-9,然后拼接。
int num = (int) (Math.random() * 10);
code += num;
break;
case 1:
// 7、如果当前位置是大写字母,则随机生成一个字母A-Z,然后拼接。 'A' 65 'Z' 65+25
int num1 = (int) (Math.random() * 26); // [0,25]
char ch = (char) (65 + num1); // 得到大写字母的随机编号,转成大写字母
code += ch;
break;
case 2:
// 8、如果当前位置是小写字母,则随机生成一个字母a-z,然后拼接。 'a' 97 'z' 97+25
int num2 = (int) (Math.random() * 26); // [0,25]
char ch1 = (char) (97 + num2);
code += ch1;
break;
}
}
return code;
}
}
public class Test {
public static void main(String[] args) {
// 目标:认识static修饰和不修饰方法的区别
// 1、类名.静态方法(推荐)
Student.printHelloWorld();
// 2、对象.静态方法(不推荐)
Student s1 = new Student();
s1.printHelloWorld();
// 3、对象名.实例方法
// Student.printPass(); // 报错
s1.setScore(59.5);
s1.printPass();
// 规范:如果这个方法只是为了做一个功能且不需要直接访问对象的数据,这个方法直接定义成静态方法
// 如果这个方法是对象的行为,需要访问对象的数据,这个方法必须定义成实例方法
// Test.printHelloWorld2();
printHelloWorld2();
}
public static void printHelloWorld2(){
System.out.println("Hello World");
System.out.println("Hello World");
System.out.println("Hello World");
System.out.println("Hello World");
}
}
public class Test2 {
public static void main(String[] args) {
// 目标:搞清楚静态方法的应用:可以做工具类。
// 登录界面
// 开发一个验证码程序
String code = VerifyCodeUtil.getCode(4);
System.out.println(code);
System.out.println(Math.random()); // [0.0 - 1.0)
}
}
public class Test3 {
public static void main(String[] args) {
// 目标:搞清楚静态方法的应用:可以做工具类。
// 注册界面
// 开发一个验证码程序
String code = VerifyCodeUtil.getCode(6);
System.out.println(code);
}
}
public class Test4 {
// 静态变量
public static int count = 100;
// 静态方法
public static void printHelloWorld2(){
System.out.println("Hello World!");
}
// 实例变量 :属于对象的。
private String name;
// 实例方法 :属于对象的。
public void run(){
}
public static void main(String[] args) {
// 目标:搞清楚静态方法,实例方法访问的几点注意事项。
printHelloWorld();
}
// 1、静态方法中可以直接访问静态成员,不可以直接访问实例成员。
public static void printHelloWorld(){
System.out.println(count);
printHelloWorld2();
// System.out.println(name); // 报错
// run(); // 报错
// System.out.println(this); // 报错。this代表的只能是对象。
}
// 2、实例方法中既可以直接访问静态成员,也可以直接访问实例成员。
// 3、实例方法中可以出现this关键字,静态方法中不可以出现this关键字的。
public void go(){
System.out.println(count);
printHelloWorld2();
System.out.println(name);
run();
System.out.println(this);
}
}
4.8实战案例
public class Movie {
private int id; // 编号
private String name;
private double price;
private String actor;
public Movie() {
}
// 定义一个有参数构造器
public Movie(int id, String name, double price, String actor) {
this.id = id;
this.name = name;
this.price = price;
this.actor = actor;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getActor() {
return actor;
}
public void setActor(String actor) {
this.actor = actor;
}
}
import java.util.Scanner;
// 电影操作类
public class MovieOperator {
private Movie[] movies; // 记住一个电影对象的数组。
public MovieOperator(Movie[] movies) {
this.movies = movies;
}
// 打印全部电影信息
public void printAllMovies() {
System.out.println("================全部电影信息如下===============");
for (int i = 0; i < movies.length; i++) {
// i = 0 1 2 3 4 5
Movie m = movies[i];
System.out.println( m.getId() + "\t" + m.getName() + "\t" + m.getPrice() + "\t" + m.getActor() + "\t" );
}
}
// 根据id查询电影
public void searchMovieById() {
System.out.println("请输入要查询的电影id:");
Scanner sc = new Scanner(System.in);
int id = sc.nextInt();
// 遍历每个电影对象
for (int i = 0; i < movies.length; i++) {
// 拿到当前遍历到的电影对象
Movie m = movies[i];
// 判断当前电影对象的id是否是我们正在找的电影id,是则打印出该电影信息并立即结束方法
if (m.getId() == id) {
System.out.println(m.getId() + "\t" + m.getName() + "\t" + m.getPrice() + "\t" + m.getActor() + "\t" );
return;
}
}
System.out.println("没有找到该电影");
}
}
public class Test {
public static void main(String[] args) {
// 目标:完成面向对象的综合小案例。
// 1、设计电影类Movie,以便创建电影对象,封装电影数据。
// 2、封装系统中的全部电影数据。(自己造一些数据)
Movie[] movies = new Movie[6];
// movies = [null, null, null, null, null, null]
// 0 1 2 3 4 5
movies[0] = new Movie(1, "星际穿越", 9.6, "安妮海瑟薇");
movies[1] = new Movie(2, "速度与激情8", 9.2, "瑞秋·费尔南多");
movies[2] = new Movie(3, "夏洛特烦恼", 9.2, "沈腾");
movies[3] = new Movie(4, "战狼2", 9.2, "吴京");
movies[4] = new Movie(5, "让子弹飞", 9.2, "姜文");
movies[5] = new Movie(6, "暗战", 9.2, "王大陆、渣渣辉");
// 3、创建电影操作对象出来,专门负责电影数据的业务操作。
MovieOperator mo = new MovieOperator(movies);
mo.printAllMovies(); // ALT + ENTER
mo.searchMovieById();
}
}
5-继承多态
5.1继承(一)
// 父类
// 继承的好处:1.代码复用 2.减少了重复代码。
public class People {
private String name;
private char sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
}
// 咨询师类:子类
public class Consultant extends People{
private int number;
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
}
// 子类
public class Teacher extends People{
private String skill; // 技术。
public String getSkill() {
return skill;
}
public void setSkill(String skill) {
this.skill = skill;
}
}
public class Test {
public static void main(String[] args) {
// 目标:认识继承,好处。
// 1、创建对象,封装老师数据
// 子类可以继承父类的非私有成员。
// 子类对象其实是由子类和父类多张设计图共同创建出来的对象,所以子类对象是完整的。
Teacher t = new Teacher();
t.setName("dlei");
t.setSkill("java、前端、大数据");
t.setSex('男');
System.out.println(t.getName());
System.out.println(t.getSkill());
System.out.println(t.getSex());
}
}
5.2继承(二)
public class Fu {
// 1、private:只能当前类中访问。
private void privateMethod(){
System.out.println("privateMethod");
}
// 2、缺省:只能当前类中,同一个包下的其他类中
void method(){
System.out.println("method");
}
// 3、protected:只能当前类中,同一个包下的其他类中,子孙类中访问
protected void protectedMethod(){
System.out.println("protectedMethod");
}
// 4、public:任何类中都可以访问
public void publicMethod(){
System.out.println("publicMethod");
}
public static void main(String[] args) {
Fu fu = new Fu();
fu.privateMethod();
fu.method();
fu.protectedMethod();
fu.publicMethod();
}
}
public class Test {
public static void main(String[] args) {
// 目标:认识四种权限修饰符的修饰范围。
Fu fu = new Fu();
// fu.privateMethod();
fu.method();
fu.protectedMethod();
fu.publicMethod();
}
}
5.3继承(三)
import com.extends2modifier.Fu;
public class Zi extends Fu {
public void show(){
// privateMethod();
// method();
protectedMethod();
publicMethod();
}
}
public class Demo {
public static void main(String[] args) {
Fu fu = new Fu();
// fu.privateMethod();
// fu.method();
// fu.protectedMethod();
fu.publicMethod();
}
}
5.4继承(四)
public class Test {
public static void main(String[] args) {
// 目标:继承的注意事项:继承的特点。
A a = new A();
}
}
// 1、java的类只能是单继承的,不支持多继承,支持多层继承
// 2、一个类要么直接继承Object,要么默认继承Object,要么间接继承Object
class A { }
class B extends A{ }
class C extends B{ }
public class Test2 {
public static void main(String[] args) {
// 目标2:继承后子类的访问特点:就近原则。
Zi zi = new Zi();
zi.show();
}
}
class Fu{
String name = "fu的name";
public void run(){
System.out.println("fu类的run方法");
}
}
class Zi extends Fu{
String name = "zi的name";
public void show() {
String name = "show的name";
System.out.println(name); // show的name
System.out.println(this.name); // zi的name
System.out.println(super.name); // fu的name
run(); // 子类的
super.run(); // 父类的
}
public void run(){
System.out.println("zi类的run方法");
}
}
5.5继承(五)
public class Test {
public static void main(String[] args) {
// 目标:认识方法重写,再搞清楚场景。
Cat cat = new Cat();
cat.cry();
}
}
class Cat extends Animal{
// 方法重写: 方法名称,形参列表必须一样,这个方法就是方法重写。
// 重写的规范:声明不变,重新实现。
@Override // 方法重写的校验注解(标志):要求方法名称和形参列表必须与被重写方法一致,否则报错! 更安全,可读性好,更优雅!
public void cry(){
System.out.println("🐱喵喵喵的叫~~~");
}
}
class Animal{
public void cry(){
System.out.println("动物会叫~~~");
}
}
public class Test2 {
public static void main(String[] args) {
// 目标:方法重写的常见应用场景:子类重写Object的toString方法,以便返回对象的内容。
Student s = new Student("赵敏", '女', 25);
//System.out.println(s.toString()); // com.itheima.extends5override.Student@b4c966a 所谓的地址
System.out.println(s); // com.itheima.extends5override.Student@b4c966a 所谓的地址
// 注意1:直接输出对象,默认会调用Object的toString方法(可以省略不写调用toString的代码),返回对象的地址信息
// 注意2:输出对象的地址实际上是没有什么意义的,开发中更希望输出对象时看对象的内容信息,所以子类需要重写Object的toString方法。
// 以便以后输出对象时默认就近调用子类重写的toString方法返回对象的内容。
}
}
class Student {
private String name;
private char sex;
private int age;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", sex=" + sex +
", age=" + age +
'}';
}
public Student() {
}
public Student(String name, char sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
5.6继承(六)
public class Test2 {
public static void main(String[] args) {
// 目标:方法重写的常见应用场景:子类重写Object的toString方法,以便返回对象的内容。
Student s = new Student("赵敏", '女', 25);
//System.out.println(s.toString()); // com.itheima.extends5override.Student@b4c966a 所谓的地址
System.out.println(s); // com.itheima.extends5override.Student@b4c966a 所谓的地址
// 注意1:直接输出对象,默认会调用Object的toString方法(可以省略不写调用toString的代码),返回对象的地址信息
// 注意2:输出对象的地址实际上是没有什么意义的,开发中更希望输出对象时看对象的内容信息,所以子类需要重写Object的toString方法。
// 以便以后输出对象时默认就近调用子类重写的toString方法返回对象的内容。
}
}
class Student {
private String name;
private char sex;
private int age;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", sex=" + sex +
", age=" + age +
'}';
}
public Student() {
}
public Student(String name, char sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class Student {
private String name;
private char sex;
private int age;
private String schoolName;
public Student() {
}
public Student(String name, char sex, int age) {
// this调用兄弟构造器。
// 注意:super(...) this(...) 必须写在构造器的第一行,而且两者不能同时出现。
this(name, sex, age, "黑马程序员");
}
public Student(String name, char sex, int age, String schoolName) {
// super(); // 必须在第一行
this.name = name;
this.sex = sex;
this.age = age;
this.schoolName = schoolName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSchoolName() {
return schoolName;
}
public void setSchoolName(String schoolName) {
this.schoolName = schoolName;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", sex=" + sex +
", age=" + age +
", schoolName='" + schoolName + '\'' +
'}';
}
}
// 子类
public class Teacher extends People {
private String skill; // 技术。
public Teacher() {
}
public Teacher(String name, String skill, char sex) {
// 子类构造器调用父类构造器的应用场景。
// 可以把子类继承自
super(name, sex);
this.skill = skill;
}
public String getSkill() {
return skill;
}
public void setSkill(String skill) {
this.skill = skill;
}
}
public class Test {
public static void main(String[] args) {
// 目标:认识子类构造器的特点,再看应用场景。
// 子类构造器都会必须先调用父类的构造器,再执行自己的构造器。
Zi z = new Zi();
}
}
class Zi extends Fu {
public Zi() {
// super(); // 默认存在的,写不写都有!
// super(666); // 指定调用父类的有参数构造器。
System.out.println("子类无参构造器执行了");
}
}
class Fu {
public Fu() {
System.out.println("父类无参构造器执行了");
}
public Fu(int a) {
System.out.println("父类有参构造器执行了");
}
}
public class Test2 {
public static void main(String[] args) {
// 目标:子类构造器调用父类构造器的应用场景。
Teacher t = new Teacher("dlei", "java、大数据、微服务", '男');
System.out.println(t.getName());
System.out.println(t.getSkill());
System.out.println(t.getSex());
}
}
public class Test3 {
public static void main(String[] args) {
// 目标:理解this(...)调用兄弟构造器
// 创建对象,存储一个学生的数据。
Student s1 = new Student("张无忌", '男', 23);
System.out.println(s1);
Student s2 = new Student("赵敏", '女', 19, "清华大学");
System.out.println(s2);
}
}
5.7多态(一)
public class Animal {
String name = "动物";
public void run(){
System.out.println("动物会跑~~~");
}
}
public class Tortoise extends Animal{
String name = "乌龟";
@Override
public void run() {
System.out.println("🐢跑的贼慢~~~");
}
}
public class Wolf extends Animal{
String name = "狼";
@Override
public void run() {
System.out.println("🐺跑的贼溜~~~");
}
}
public class Test {
public static void main(String[] args) {
// 目标:认识多态的代码。
// 1、对象多态、行为多态。
Animal a1 = new Wolf();
a1.run(); // 方法:编译看左边,运行看右边
System.out.println(a1.name); // 成员变量:编译看左边,运行也看左边
Animal a2 = new Tortoise();
a2.run(); // 方法:编译看左边,运行看右边
System.out.println(a2.name); // 成员变量:编译看左边,运行也看左边
}
}
5.8多态(二)
public class Animal {
String name = "动物";
public void run(){
System.out.println("动物会跑~~~");
}
}
public class Tortoise extends Animal {
String name = "乌龟";
@Override
public void run() {
System.out.println("🐢跑的贼慢~~~");
}
public void shrinkHead() {
System.out.println("乌龟缩头了~~~");
}
}
public class Wolf extends Animal {
String name = "狼";
@Override
public void run() {
System.out.println("🐺跑的贼溜~~~");
}
public void eatSheep() {
System.out.println("狼吃羊");
}
}
public class Test {
public static void main(String[] args) {
// 目标:认识多态的代码。
// 1、多态的好处1: 右边对象是解耦合的。
Animal a1 = new Tortoise();
a1.run();
// a1.shrinkHead(); // 多态下的一个问题:多态下不能调用子类独有功能。
Wolf w = new Wolf();
go(w);
Tortoise t = new Tortoise();
go(t);
}
// 宠物游戏:所有动物都可以送给这个方法开始跑步。
// 2、多态的好处2:父类类型的变量作为参数,可以接收一个子类对象
public static void go(Animal a){
System.out.println("开始。。。。。");
a.run();
// a1.shrinkHead(); // 报错,多态下不能调用子类独有功能。
}
}
5.9多态(三)
public class Animal {
String name = "动物";
public void run(){
System.out.println("动物会跑~~~");
}
}
public class Tortoise extends Animal {
String name = "乌龟";
@Override
public void run() {
System.out.println("🐢跑的贼慢~~~");
}
public void shrinkHead() {
System.out.println("乌龟缩头了~~~");
}
}
public class Wolf extends Animal {
String name = "狼";
@Override
public void run() {
System.out.println("🐺跑的贼溜~~~");
}
public void eatSheep() {
System.out.println("狼吃羊");
}
}
public class Test {
public static void main(String[] args) {
// 目标:认识多态的代码。
// 1、多态的好处1: 右边对象是解耦合的。
Animal a1 = new Tortoise();
a1.run();
// a1.shrinkHead(); // 多态下的一个问题:多态下不能调用子类独有功能。
// 强制类型转换:可以解决多态下调用子类独有功能
Tortoise t1 = (Tortoise) a1;
t1.shrinkHead();
// 有继承关系就可以强制转换,编译阶段不会报错!
// 运行时可能会出现类型转换异常:ClassCastException
// Wolf w1 = (Wolf) a1;
System.out.println("=======================");
Wolf w = new Wolf();
go(w);
Tortoise t = new Tortoise();
go(t);
}
public static void go(Animal a){
System.out.println("开始。。。。。");
a.run();
// a1.shrinkHead(); // 报错,多态下不能调用子类独有功能。
// java建议强制转换前,应该判断对象的真实类型,再进行强制类型转换。
if(a instanceof Wolf){
Wolf w1 = (Wolf) a;
w1.eatSheep();
}else if(a instanceof Tortoise){
Tortoise t1 = (Tortoise) a;
t1.shrinkHead();
}
}
}
5.10实战案例
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
// lombok技术可以实现为类自动添加getter setter方法 无参数构造器,toString方法等。
//@Data // @Data注解可以自动生成getter setter方法 无参构造器 toString方法等
//@NoArgsConstructor
//@AllArgsConstructor
//public class Card {
// private String carId; // 车牌号码
// private String name;
// private String phone;
// private double money; // 余额
//
// // 预存金额。
// public void deposit(double money) {
// this.money += money;
// }
//
// // 消费金额。
// public void consume(double money) {
// this.money -= money;
// }
//}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Card {
private String carId; // 卡牌号码
private String name;
private String phone;
private double money; // 余额
// 预存金额。
public void deposit(double money) {
this.money += money;
}
// 消费金额。
public void consume(double money) {
this.money -= money;
}
}
public class GoldCard extends Card{
public GoldCard(String card, String name, String phone, double money) {
super(card, name, phone, money);
}
@Override
public void consume(double money) {
System.out.println("您当前金卡消费:" + money);
System.out.println("优惠后的价格:" + money * 0.8);
if(getMoney() < money * 0.8){
System.out.println("您余额是:" + getMoney() + ", 当前余额不足!请存钱!");
return; // 干掉方法!
}
// 更新金卡的账户余额。
setMoney(getMoney() - money * 0.8);
System.out.println("您当前金卡余额:" + getMoney());
// 判断消费如果大于200,调用一个独有的功能,打印洗车票。
if(money * 0.8 >= 200){
printTicket();
}else {
System.out.println("您当前消费不满200,不能免费洗车!");
}
}
// 打印洗车票。
public void printTicket() {
System.out.println("您消费了,请打印洗车票。");
}
}
public class SilverCard extends Card{
public SilverCard(String card, String name, String phone, double money) {
super(card, name, phone, money);
}
@Override
public void consume(double money) {
System.out.println("您当前银卡消费:" + money);
System.out.println("优惠后的价格:" + money * 0.9);
if(getMoney() < money * 0.9){
System.out.println("您余额是:" + getMoney() + ", 当前余额不足!请存钱!");
return; // 干掉方法!
}
// 更新金卡的账户余额。
setMoney(getMoney() - money * 0.9);
System.out.println("您当前金卡余额:" + getMoney());
}
}
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
// 目标:加油站支付小程序。
// 1、创建卡片类,以便创建金卡或者银卡对象,封装车主的数据。
// 2、定义一个卡片父类:Card,定义金卡和银卡的共同属性和方法。
// 3、定义一个金卡类,继承Card类:金卡必须重写消费方法(8折优惠),独有功能打印洗车票。
// 3、定义一个银卡类,继承Card类:银卡必须重写消费方法(9折优惠)
// 4、办一张金卡:创建金卡对象。交给一个独立的业务(支付机)来完成:存款,消费。
GoldCard goldCard = new GoldCard("鄂A860MM", "dlei", "18665616520", 5000);
goldCard.deposit(100); // 再存100
pay(goldCard);
// 4、办一张银卡:创建银卡对象。交给一个独立的业务(支付机)来完成:存款,消费。
SilverCard silverCard = new SilverCard("粤A88888", "dlei", "18984724244", 2000);
pay(silverCard);
}
// 支付机:用一个方法来刷卡: 可能接收金卡,也可能接收银卡。
public static void pay(Card c){
System.out.println("请刷卡,请您输入当前消费的金额:");
Scanner sc = new Scanner(System.in);
double money = sc.nextDouble();
c.consume(money);
}
}
6-final关键字/抽象类跟接口
6.1-final
public class Constant {
public static final String SYSTEM_NAME = "智能家居AI系统";
}
public class FinalDemo1 {
// final修饰静态成员变量
// final修饰静态变量,这个变量今后被称为常量,可以记住一个固定值,并且程序中不能修改了,通常这个值作为系统的配置信息。
// 常量的名称,建议全部大写,多个单词用下划线链接
public static final String SCHOOL_NAME = "程序员";
// final修饰实例变量(一般没有意义)
private final String name = "猪刚鬣";
public static void main(String[] args) {
// 目标:认识final关键字的作用。
// 3、final修饰变量:变量有且仅能被赋值一次。
/*
变量有哪些呢?
a、成员变量:
静态成员变量
实例成员变量
b、局部变量
*/
final double rate = 3.14;
// rate = 3.16; // 第二次赋值,报错。
buy(0.8);
FinalDemo1 f = new FinalDemo1();
System.out.println(f.name);
// f.name = "高翠兰"; // 第二次赋值,报错。
final int a = 20;
// a = 30; // 第二次赋值,报错。
final int[] arr = {11, 22, 33, 44};
// arr = new int[]{33, 55, 44}; // 第二次赋值,报错。
arr[2] = 90;
}
public static void buy(final double z){
// z = 0.1; // 第二次赋值,报错。
System.out.println(z);
}
}
// 1、final修饰类,类不能被继承。
final class A{
}
// class B extends A{}
// 2、final修饰方法,方法不能被重写。
class C{
public final void show(){
System.out.println("show方法被执行");
}
}
class D extends C{
// @Override
// public void show(){
// System.out.println("show方法被执行");
// }
}
public class FinalDemo2 {
public static void main(String[] args) {
// 目标:详解常量。
System.out.println(Constant.SYSTEM_NAME);
System.out.println(Constant.SYSTEM_NAME);
System.out.println(Constant.SYSTEM_NAME);
System.out.println(Constant.SYSTEM_NAME);
System.out.println(Constant.SYSTEM_NAME);
System.out.println(Constant.SYSTEM_NAME);
}
}
6.2-enum
// 枚举类
public enum A {
// 枚举类的第一行:只能罗列枚举对象的名称,这些名称本质是常量。
X, Y, Z;
}
public enum Direction {
UP, DOWN, LEFT, RIGHT;
}
public class Constant {
public static final int UP = 0; // 上
public static final int DOWN = 1; // 下
public static final int LEFT = 2; // 左
public static final int RIGHT = 3; // 右
}
public class Test {
public static void main(String[] args) {
// 目标:认识枚举类,搞清楚其本质特点。
A a1 = A.X;
System.out.println(a1);
A a2 = A.Y;
System.out.println(a2);
System.out.println(a1.name()); // X
System.out.println(a2.name()); // Y
System.out.println(a1.ordinal()); // 索引 0
System.out.println(a2.ordinal()); // 索引 1
}
}
public class Test2 {
public static void main(String[] args) {
// 目标:掌握枚举类的应用场景:做信息的分类和标志。
// 需求:模拟上下左右移动图片。
// 第一种是常量做信息标志和分类: 但参数值不受约束。
move(Constant.UP);
// 第二种是枚举做信息标志和分类: 参数值受枚举类约束。
move2(Direction.DOWN);
}
public static void move2(Direction direction){
// 根据这个方向做移动:上下左右。
switch (direction){
case UP :
System.out.println("向上移动");
break;
case DOWN :
System.out.println("向下移动");
break;
case LEFT :
System.out.println("向左移动");
break;
case RIGHT :
System.out.println("向右移动");
break;
}
}
public static void move(int direction){
// 根据这个方向做移动:上下左右。
switch (direction){
case Constant.UP :
System.out.println("向上移动");
break;
case Constant.DOWN :
System.out.println("向下移动");
break;
case Constant.LEFT :
System.out.println("向左移动");
break;
case Constant.RIGHT :
System.out.println("向右移动");
break;
default:
System.out.println("输入有误");
}
}
}
6.3抽象类(一)
// 抽象类
public abstract class A {
private String name;
private int age;
public A() {
System.out.println("A的无参构造器");
}
public A(String name, int age) {
this.name = name;
this.age = age;
}
// 抽象方法:必须用abstract修饰,没有方法体,只有方法声明。
public abstract void show();
public void show1() {
System.out.println("show1方法");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
// 一个类继承抽象类,必须重写完继承的全部抽象方法,否则这个类也必须定义成抽象类
public class B extends A{
@Override
public void show() {
System.out.println("B类重写show方法");
}
}
public class AbstractDemo1 {
public static void main(String[] args) {
// 目标:认识抽象类,抽象方法,搞清楚他们的特点。
// 抽象类的核心特点:有得有失(得到了抽象方法的能力,失去了创建对象的能力)
// 抽象类不能创建对象(重点)。
// A a = new A(); // 报错了
// 抽象类的使命就是被子类继承:就是为了生孩子。
B b = new B();
b.setName("张三");
b.setAge(18);
System.out.println(b.getName() + "---" + b.getAge());
b.show();
b.show1();
}
}
6.4抽象类(二)
public abstract class Animal {
// 每个动物的叫声。
public abstract void cry();
}
public class Cat extends Animal{
@Override
public void cry() {
System.out.println("🐱是喵喵喵的叫~~~");
}
}
public class Dog extends Animal{
@Override
public void cry() {
System.out.println("🐕是汪汪汪的叫~~~");
}
}
public class Test {
public static void main(String[] args) {
// 目标:搞清楚使用抽象类的好处。
Animal a = new Dog();
a.cry();
}
}
6.5抽象类(三)
public abstract class People {
// 1、模板方法设计模式。
public final void write(){
System.out.println("\t\t\t《我的爸爸》");
System.out.println("\t我爸爸是一个好人,我特别喜欢他,他对我很好,我来介绍一下:");
// 2、模板方法知道子类一定要写这个正文,但是每个子类写的信息是不同的,父类定义一个抽象方法
// 具体的实现交给子类来重写正文。
writeMain();
System.out.println("\t我爸爸真好,你有这样的爸爸吗?");
}
public abstract void writeMain();
}
public class Student extends People{
@Override
public void writeMain() {
System.out.println("\t我爸爸很牛逼,是个管理者,我开车不用看红绿灯的,有这样的爸爸真好,下辈子还要做他儿子!");
}
}
public class Teacher extends People {
@Override
public void writeMain() {
System.out.println("\t我爸爸经常让我站在这里别动,他要去买几斤橘子~~柚子我也吃,毕竟是亲生的!");
}
}
public class Test {
public static void main(String[] args) {
// 目标:理解抽象类的使用场景之二:模板方法设计模式。
// 学生和老师都要写一篇作文:《我的爸爸》
// 第一段是一样的:我爸爸是一个好人,我特别喜欢他,他对我很好,我来介绍一下:
// 第二段是不一样:老师和学生各自写各自的。
// 第三段是一样的:我爸爸真好,你有这样的爸爸吗?
// 解决:抽出一个父类。父类中还抽取一个模板方法给子类直接用。
Student s = new Student();
s.write();
}
}
6.6单例模式
// 设计成单例设计模式
public class A {
// 2、定义一个静态变量,用于存储本类的一个唯一对象。
// public static final A a = new A();
private static A a = new A();
// 1、私有化构造器: 确保单例类对外不能创建太多对象,单例才有可能性。
private A() {
}
// 3、提供一个公开的静态方法,返回这个类的唯一对象。
public static A getInstance() {
return a;
}
}
// 懒汉式单例类。
public class B {
// 2、私有化静态变量
private static B b;
// 1、私有化构造器
private B() {
}
// 3、提供静态方法返回对象: 真正需要对象的时候才开始创建对象。
public static B getInstance() {
if (b == null) {
// 第一次拿对象时,会创建对象,给静态变量b记住。
b = new B();
}
return b;
}
}
public class Test {
public static void main(String[] args) {
// 目标:设计单例类。
A a1 = A.getInstance();
A a2 = A.getInstance();
System.out.println(a1);
System.out.println(a2);
System.out.println(a1 == a2);
System.out.println("============================");
B b1 = B.getInstance();
B b2 = B.getInstance();
System.out.println(b1);
System.out.println(b2);
System.out.println(b1 == b2);
}
}
6.7接口(一)
// 接口:使用interface关键字定义的
public interface A {
// JDK 8之前,接口中只能定义常量和抽象方法。
// 1、常量:接口中定义常量可以省略public static final不写,默认会加上去。
String SCHOOL_NAME = "程序员";
// public static final String SCHOOL_NAME2 = "黑马程序员";
// 2、抽象方法: 接口中定义抽象方法可以省略public abstract不写,默认会加上去。
// public abstract void run();
void run();
String go();
}
public interface B {
void play(); // 玩
}
public class Test {
public static void main(String[] args) {
// 目标:认识接口,搞清楚接口的特点,基本使用.
System.out.println(A.SCHOOL_NAME);
// 注意:接口不能创建对象。
// 接口是用来被类实现的。
C c = new C();
c.run();
System.out.println(c.go());
c.play();
}
}
// C被称为实现类。同时实现了多个接口。
// 实现类实现多个接口,必须重写完全部接口的全部抽象方法,否则这个类必须定义成抽象类
class C implements B , A{
@Override
public void run() {
System.out.println("C类重写了run方法");
}
@Override
public String go() {
return "找磊哥!";
}
@Override
public void play() {
System.out.println("C类重写了play方法");
}
}
6.8接口(二)
public class Test {
public static void main(String[] args) {
// 目标:去理解Java设计接口的好处、用处。
// 接口弥补了类单继承的不足,可以让类拥有更多角色,类的功能更强大。
People p = new Student();
Driver d = new Student(); // 多态
BoyFriend bf = new Student();
// 接口可以实现面向接口编程,更利于解耦合。
Driver a = new Student();
Driver a2 = new Teacher();
BoyFriend b1 = new Student();
BoyFriend b2 = new Teacher();
}
}
interface Driver{}
interface BoyFriend{}
class People{}
class Student extends People implements Driver, BoyFriend{}
class Teacher implements Driver, BoyFriend{}
6.9接口(三)
public interface ClassDataInter {
void printAllStudentInfos();
void printAverageScore();
}
public class ClassDataInterImpl1 implements ClassDataInter{
private Student[] students; // 记住送来的全班学生对象信息。
public ClassDataInterImpl1(Student[] students) {
this.students = students;
}
@Override
public void printAllStudentInfos() {
System.out.println("全班学生信息如下:");
for (int i = 0; i < students.length; i++) {
Student s = students[i];
System.out.println(s.getName() + " " + s.getSex() + " " + s.getScore());
}
}
@Override
public void printAverageScore() {
double sum = 0;
for (int i = 0; i < students.length; i++) {
Student s = students[i];
sum += s.getScore();
}
System.out.println("全班平均成绩为:" + sum / students.length);
}
}
// -- 定义第二套实现类,实现接口:实现打印学生信息(男女人数),实现打印平均分(去掉最高分和最低分)。
public class ClassDataInterImpl2 implements ClassDataInter{
private Student[] students; // 记住送来的全班学生对象信息。
public ClassDataInterImpl2(Student[] students) {
this.students = students;
}
@Override
public void printAllStudentInfos() {
System.out.println("学生信息如下:");
int maleCount = 0; // 男生人数
for (int i = 0; i < students.length; i++) {
Student s = students[i];
System.out.println(s.getName() + " " + s.getSex() + " " + s.getScore());
if (s.getSex() == '男') {
maleCount++;
}
}
System.out.println("男学生人数:" + maleCount);
System.out.println("女学生人数:" + (students.length - maleCount));
}
// 实现打印平均分(去掉最高分和最低分)
@Override
public void printAverageScore() {
System.out.println("平均分如下:");
Student s1 = students[0];
double sum = s1.getScore();
double max = s1.getScore();
double min = s1.getScore();
for (int i = 1; i < students.length; i++) {
Student s = students[i];
sum += s.getScore();
if(s.getScore() > max) {
max = s.getScore();
}
if(s.getScore() < min) {
min = s.getScore();
}
}
System.out.println("最高分:" + max);
System.out.println("最低分:" + min);
System.out.println("平均分:" + (sum - max - min) / (students.length - 2));
}
}
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
private String name;
private char sex;
private double score;
}
public class Test {
public static void main(String[] args) {
// 目标:完成接口的小案例。
// 1、定义学生类,创建学生对象,封装学生数据,才能交给别人处理学生的数据。
// 2、准备学生数据,目前我们自己造一些测试数据
Student[] allStudents = new Student[10];
allStudents[0] = new Student("张三", '男', 100);
allStudents[1] = new Student("李四", '女', 99);
allStudents[2] = new Student("王五", '男', 98);
allStudents[3] = new Student("赵六", '女', 97);
allStudents[4] = new Student("孙七", '男', 96);
allStudents[5] = new Student("周八", '女', 95);
allStudents[6] = new Student("吴九", '男', 94);
allStudents[7] = new Student("郑十", '女', 93);
allStudents[8] = new Student("赵敏", '女', 100);
allStudents[9] = new Student("周芷若", '女', 90);
// 3、提供两套业务实现方案,支持灵活切换(解耦合): 面向接口编程。
// -- 定义一个接口(规范思想):必须完成打印全班学生信息,打印平均分。(ClassDataInter)
// -- 定义第一套实现类,实现接口:实现打印学生信息,实现打印平均分。
// -- 定义第二套实现类,实现接口:实现打印学生信息(男女人数),实现打印平均分(去掉最高分和最低分)。
ClassDataInter cdi = new ClassDataInterImpl2(allStudents);
cdi.printAllStudentInfos();
cdi.printAverageScore();
}
}
6.10接口(四)
public interface A {
// 1、默认方法(普通实例方法):必须加default修饰,
// 默认会用public修饰。
// 如何调用? 使用接口的实现类的对象来调用。
default void go(){
System.out.println("==go方法执行了===");
run();
}
// 2、私有方法(JDK 9开始才支持的)
// 私有的实例方法。
// 如何调用? 使用接口中的其他实例方法来调用它
private void run(){
System.out.println("==run方法执行了===");
}
// 3、静态方法
// 默认会用public修饰。
// 如何调用? 只能使用当前接口名来调用。
static void show(){
System.out.println("==show方法执行了===");
}
}
public class Test {
public static void main(String[] args) {
// 目标:搞清楚接口JDK 8新增的三种方法,并理解其好处。
AImpl a = new AImpl();
a.go();
A.show(); // 静态方法'
}
}
class AImpl implements A{
}
6.11接口(五)
public class Test {
public static void main(String[] args) {
// 目标:理解接口的几点注意事项。
Dog d = new Dog();
d.go();
}
}
// 4、一个类实现了多个接口,如果多个接口中存在同名的默认方法,可以不冲突,这个类重写该方法即可。
interface A3 {
default void show(){
System.out.println("接口中的 A3 show 方法");
}
}
interface B3 {
default void show(){
System.out.println("接口中的 B3 show 方法");
}
}
class Dog2 implements A3, B3 {
@Override
public void show() {
A3.super.show(); // A3干爹的
B3.super.show(); // B3干爹的
}
}
// 3、一个类继承了父类,又同时实现了接口,如果父类中和接口中有同名的方法,实现类会优先用父类的。[了解]
interface A2 {
default void show(){
System.out.println("接口中的 A2 show 方法");
}
}
class Animal{
public void show(){
System.out.println("父类中的 show 方法");
}
}
class Dog extends Animal implements A2 {
public void go(){
show(); // 父类的
super.show(); // 父类的
A2.super.show(); // A2接口的方法
}
}
// 2、一个接口继承多个接口,如果多个接口中存在方法签名冲突,则此时不支持多继承,也不支持多实现。[了解]
interface A1 {
void show();
}
interface B1 {
String show();
}
//interface C1 extends A1, B1 {
//}
//class D1 implements A1, B1{
//}
// 1、接口与接口可以多继承:一个接口可以同时继承多个接口[重点]。
// 类与类: 单继承 一个类只能继承一个直接父类
// 类与接口:多实现,一个类可以同时实现多个接口。
// 接口与接口: 多继承,一个接口可以同时继承多个接口。
interface A {
void show1();
}
interface B {
void show2();
}
interface C extends B , A{
void show3();
}
class D implements C{
@Override
public void show3() {
}
@Override
public void show1() {
}
@Override
public void show2() {
}
}
6.12实战案例
public interface Switch {
void press(); // 按压
}
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
// 家电
@Data
@NoArgsConstructor
@AllArgsConstructor
public class JD implements Switch{
private String name;
// 状态:开或者关。
private boolean status; // false 默认是关闭。
@Override
public void press() {
// 控制当前设备开和关
status = !status;
}
}
public class Air extends JD{
public Air(String name, boolean status) {
super(name, status);
}
}
public class Lamp extends JD{
public Lamp(String name, boolean status) {
super(name, status);
}
}
public class TV extends JD{
public TV(String name, boolean status) {
super(name, status);
}
}
// 洗衣机
public class WashMachine extends JD{
public WashMachine(String name, boolean status) {
super(name, status);
}
}
// 智能控制系统类。
public class SmartHomeControl {
// 多态。
public void control(JD jd) {
System.out.println(jd.getName() + "状态目前是:" + (jd.isStatus() ? "开着" : "关闭!"));
System.out.println("开始您的操作。。。。。");
jd.press(); // 按下开关。
System.out.println(jd.getName() + "状态已经是:" + (jd.isStatus() ? "开着" : "关闭!"));
}
public void printAllStatus(JD[] jds) {
// 使用for循环,根据索引遍历每个设备。
for (int i = 0; i < jds.length; i++) {
JD jd = jds[i];
System.out.println((i + 1) + "," + jd.getName() + "状态目前是:" + (jd.isStatus() ? "开着" : "关闭!"));
}
}
}
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
// 目标:面向对象编程实现智能家居控制系统。
// 角色:设备(吊灯,电视机,洗衣机,落地窗,....)
// 具备的功能:开和关。
// 谁控制他们:智能控制系统(单例对象),控制调用设备的开和关。
// 1、定义设备类:创建设备对象代表家里的设备。
// 2、准备这些设备对象,放到数组中,代表整个家庭的设备。
JD[] jds = new JD[4];
jds[0] = new TV("小米电视", true);
jds[1] = new WashMachine("美的洗衣机", false);
jds[2] = new Lamp("欧灯", true);
jds[3] = new Air("美的空调", false);
// 3、为每个设备制定一个开个关的功能。定义一个接口,让JD实现开关功能。
// 4、创建智能控制系统对象,控制设备开和关。
SmartHomeControl smartHomeControl = new SmartHomeControl();
// 5、控制电视机。
// smartHomeControl.control(jds[0]);
// 6 、提示用户操作,a、展示全部设备的当前情况。b、让用户选择哪一个操作。
// 打印全部设备的开和关的现状。
while (true) {
smartHomeControl.printAllStatus(jds);
System.out.println("请您选择要控制的设备:");
Scanner sc = new Scanner(System.in);
String command = sc.next();
switch (command){
case "1":
smartHomeControl.control(jds[0]);
break;
case "2":
smartHomeControl.control(jds[1]);
break;
case "3":
smartHomeControl.control(jds[2]);
break;
case "4":
smartHomeControl.control(jds[3]);
break;
case "exit":
System.out.println("退出App!");
return;
default:
System.out.println("输入有误,请重新输入");
}
}
}
}
7-内部类/函数式编程/常用API
7.1代码块
import java.util.Arrays;
public class CodeDemo1 {
public static String schoolName;
public static String[] cards = new String[54];
// 静态代码块:有static修饰,属于类,与类一起优先加载,自动执行一次
// 基本作用:可以完成对类的静态资源的初始化
static {
System.out.println("===静态代码块执行了====");
schoolName = "程序员";
cards[0] = "A";
cards[1] = "2";
cards[2] = "3";
// ...
}
public static void main(String[] args) {
// 目标: 认识代码块,搞清楚代码块的基本作用。
System.out.println("===main方法执行了====");
System.out.println(schoolName);
System.out.println(Arrays.toString(cards)); // 返回数组的内容观察
}
}
public class CodeDemo2 {
private String name;
private String[] direction = new String[4]; // 实例变量
// 实例代码块:无static修饰。属于对象,每次创建对象时,都会优先执行一次。
// 基本作用:初始化对象的实例资源。
{
System.out.println("=========实例代码块执行了=========");
name = "it"; // 赋值
direction[0] = "N";
direction[1] = "S";
direction[2] = "E";
direction[3] = "W";
}
public static void main(String[] args) {
// 目标:实例代码块。
System.out.println("=========main方法执行了=========");
new CodeDemo2();
new CodeDemo2();
new CodeDemo2();
}
}
7.2内部类(一)
// 外部类
public class Outer {
public static String schoolName = "程序员";
public static void test(){
System.out.println("test()");
}
private int age;
public void run(){
}
// 成员内部类:无static修饰,属于外部类的对象持有的。
public class Inner {
private String name;
// 构造器
public Inner() {
System.out.println("Inner() name = " + name);
}
// 有参数构造器
public Inner(String name) {
this.name = name;
System.out.println("Inner(String name)");
}
public void show() {
System.out.println("show");
// 成员内部类中可以直接访问外部类的静态成员
System.out.println(schoolName);
test();
// 也可以直接访问外部类的实例成员
System.out.println(age);
run();
System.out.println(this); // 自己的对象
System.out.println(Outer.this); // 寄生的外部类对象
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
public class InnerClassDemo1 {
public static void main(String[] args) {
// 目标:搞清楚成员内部类的语法。
// 成员内部类创建对象的格式:
// 外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();
Outer.Inner oi = new Outer().new Inner();
oi.setName("王麻子");
oi.show();
// 成员内部类访问外部类成员的特点(拓展):
// 1、成员内部类中可以直接访问外部类的静态成员,也可以直接访问外部类的实例成员
// 2、成员内部类的实例方法中,可以直接拿到当前寄生的外部类对象:外部类名.this
People.Heart heart = new People().new Heart();
heart.show();
}
}
class People {
private int heartBeat = 100;
public class Heart {
private int heartBeat = 80;
public void show() {
int heartBeat = 200;
System.out.println(heartBeat);// 200
System.out.println(this.heartBeat);// 80
System.out.println(People.this.heartBeat);// 100
}
}
}
7.3内部类(二)
// 外部类
public class Outer {
public static String schoolName;
private int age; // 实例成员
// 静态内部类: 属于外部类本身持有
public static class Inner{
private String name;
public void show() {
// 静态内部类中是否可以直接访问外部类的静态成员? 可以!
System.out.println(schoolName);
// 静态内部类中是否可以直接访问外部类的实例成员?不可以!
// System.out.println(age); // 报错!
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
}
public class InnerClassDemo2 {
public static void main(String[] args) {
// 目标:搞清楚静态内部类的语法。
// 创建对象:外部类名.内部类名 对象名 = new 外部类名.内部类名();
Outer.Inner inner = new Outer.Inner();
inner.show();
// 1、静态内部中是否可以直接访问外部类的静态成员? 可以!
// 2、静态内部类中是否可以直接访问外部类的实例成员?不可以!
}
}
7.4内部类(三)
public abstract class Animal {
public abstract void cry();
}
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
// 姓名 年龄 身高 性别
private String name;
private int age;
private double height;
private char sex;
}
public class Test {
public static void main(String[] args) {
// 目标:认识匿名内部类,搞清楚其基本作用。
// 匿名内部类实际上是有名字:外部类名$编号.class
// 匿名内部类本质是一个子类,同时会立即构建一个子类对象
Animal a = new Animal(){
@Override
public void cry() {
System.out.println("🐱猫是喵喵喵的叫~~~~");
}
};
a.cry();
}
}
class Cat extends Animal{
@Override
public void cry() {
System.out.println("🐱猫是喵喵喵的叫~~~~");
}
}
public class Test2 {
public static void main(String[] args) {
// 目标:搞清楚匿名内部类的使用形式(语法): 通常可以做为一个对象参数传输给方法使用。
// 需求:学生,老师都要参加游泳比赛。
Swim s1 = new Swim() {
@Override
public void swimming() {
System.out.println("学生🏊贼快~~~~");
}
};
start(s1);
System.out.println("====================================");
start(new Swim() {
@Override
public void swimming() {
System.out.println("老师🏊贼溜~~~~");
}
});
}
// 设计一个方法,可以接收老师,和学生开始比赛。
public static void start(Swim s) {
System.out.println("开始。。。。");
s.swimming();
System.out.println("结束。。。。");
}
}
interface Swim {
void swimming(); // 游泳方法
}
7.5-GUI
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Test3 {
public static void main(String[] args) {
// 目标:搞清楚几个匿名内部类的使用场景。
// 需求:创建一个登录窗口,窗口上只有一个登录按钮
JFrame win = new JFrame("登录窗口");
win.setSize(300, 200);
win.setLocationRelativeTo(null); // 居中显示。
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
win.add(panel);
JButton btn = new JButton("登录");
panel.add(btn);
// java要求必须给这个按钮添加一个点击事件监听器对象,这样就可以监听用户的点击操作,就可以做出反应。
// 开发中不是我们要主动去写匿名内部类,而是用别人的功能的时候,别人可以让我们写一个匿名内部类吗,我们才会写!!
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("登录成功!");
}
});
win.setVisible(true);
}
}
7.6排序
import java.util.Arrays;
import java.util.Comparator;
public class Test4 {
public static void main(String[] args) {
// 目标:完成给数组排序,理解其中匿名内部类的用法。
// 准备一个学生类型的数组,存放6个学生对象。
Student[] students = new Student[6];
students[0] = new Student("殷素素", 35, 171.5, '女');
students[1] = new Student("杨幂", 28, 168.5, '女');
students[2] = new Student("张无忌", 25, 181.5, '男');
students[3] = new Student("小昭", 19, 165.5, '女');
students[4] = new Student("赵敏", 27, 167.5, '女');
students[5] = new Student("刘亦菲", 36, 168, '女');
// 需求:按钮年龄升序排序。可以调用sun公司写好的API直接对数组进行排序。
// public static void sort(T[] a, Comparator<T> c)
// 参数一: 需要排序的数组
// 参数二: 需要给sort方法声明一个Comparator比较器对象(指定排序的规则)
// sort方法内部会调用匿名内部类对象的compare方法,对数组中的学生对象进行两两比较,从而实现排序。
Arrays.sort(students, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
// 指定排序规则:
// 如果你认为左边对象 大于 右边对象 那么返回正整数。
// 如果你认为左边对象 小于 右边对象 那么返回负整数。
// 如果两边相等那么返回0
// if(o1.getAge() > o2.getAge()){
// return 1;
// }else if(o1.getAge() < o2.getAge()){
// return -1;
// }
// return 0;
// return o1.getAge() - o2.getAge(); // 按照年龄升序!
return o2.getAge() - o1.getAge(); // 按照年龄降序!
}
});
// 遍历数组中的学生对象并输出
for (int i = 0; i < students.length; i++) {
Student s = students[i];
System.out.println(s);
}
}
}
7.7-lambda(一)
public class LambdaDemo1 {
public static void main(String[] args) {
// 目标:认识Lambda表达式:搞清楚其基本作用。
Animal a = new Animal() {
@Override
public void cry() {
System.out.println("🐱是喵喵喵的叫~~~~");
}
};
a.cry();
// 错误示范:Lambda并不是可以简化全部的匿名内部类,Lambda只能简化函数式接口的匿名内部类。
// Animal a1 = () -> {
// System.out.println("🐱是喵喵喵的叫~~~~");
// };
// a1.cry();
System.out.println("=====================================================");
/* Swim s1 = new Swim() {
@Override
public void swimming() {
System.out.println("学生🏊贼快~~~~");
}
}; */
// Lambda只能简化函数式接口的匿名内部类。
Swim s1 = () -> {
System.out.println("学生🏊贼快~~~~");
};
s1.swimming();
}
}
abstract class Animal{
public abstract void cry();
}
// 函数式接口:只有一个抽象方法的接口。
@FunctionalInterface // 声明函数式接口的注解。
interface Swim{
void swimming();
}
7.8-lambda(二)
import javax.swing.*;
import java.util.Arrays;
public class LamdbaDemo2 {
public static void main(String[] args) {
// 目标:用Lambda表达式简化实际示例。
test1();
test2();
}
public static void test1(){
Student[] students = new Student[6];
students[0] = new Student("殷素素", 35, 171.5, '女');
students[1] = new Student("杨幂", 28, 168.5, '女');
students[2] = new Student("张无忌", 25, 181.5, '男');
students[3] = new Student("小昭", 19, 165.5, '女');
students[4] = new Student("赵敏", 27, 167.5, '女');
students[5] = new Student("刘亦菲", 36, 168, '女');
// 需求:按钮年龄升序排序。可以调用sun公司写好的API直接对数组进行排序。
// Arrays.sort(students, new Comparator<Student>() {
// @Override
// public int compare(Student o1, Student o2) {
// return o1.getAge() - o2.getAge(); // 按照年龄升序!
// }
// });
// Arrays.sort(students, (Student o1, Student o2) -> {
// return o1.getAge() - o2.getAge(); // 按照年龄升序!
// });
// Arrays.sort(students, (o1, o2) -> {
// return o1.getAge() - o2.getAge(); // 按照年龄升序!
// });
Arrays.sort(students, (o1, o2) -> o1.getAge() - o2.getAge());
// 遍历数组中的学生对象并输出
for (int i = 0; i < students.length; i++) {
Student s = students[i];
System.out.println(s);
}
}
public static void test2(){
JFrame win = new JFrame("登录窗口");
win.setSize(300, 200);
win.setLocationRelativeTo(null); // 居中显示。
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
win.add(panel);
JButton btn = new JButton("登录");
panel.add(btn);
// java要求必须给这个按钮添加一个点击事件监听器对象,这样就可以监听用户的点击操作,就可以做出反应。
// 开发中不是我们要主动去写匿名内部类,而是用别人的功能的时候,别人可以让我们写一个匿名内部类吗,我们才会写!!
// btn.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// System.out.println("登录成功!");
// }
// });
// btn.addActionListener((ActionEvent e) -> {
// System.out.println("登录成功!");
// });
// btn.addActionListener((e) -> {
// System.out.println("登录成功!");
// });
// btn.addActionListener(e -> {
// System.out.println("登录成功!");
// });
btn.addActionListener(e -> System.out.println("登录成功!"));
win.setVisible(true);
}
}
7.9静态方法引用
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
// 姓名 年龄 身高 性别
private String name;
private int age;
private double height;
private char sex;
// 静态方法
public static int compareByAge(Student o1, Student o2) {
return o1.getAge() - o2.getAge();
}
// 实例方法
public int compareByHeight(Student o1, Student o2) {
// 按照身高比较
return Double.compare(o1.getHeight(), o2.getHeight());
}
}
7.10实例方法引用
import java.util.Arrays;
public class Demo2 {
public static void main(String[] args) {
// 目标:实例方法引用:演示一个场景。
test();
}
public static void test() {
Student[] students = new Student[6];
students[0] = new Student("殷素素", 35, 171.5, '女');
students[1] = new Student("杨幂", 28, 168.5, '女');
students[2] = new Student("张无忌", 25, 181.5, '男');
students[3] = new Student("小昭", 19, 165.5, '女');
students[4] = new Student("赵敏", 27, 167.5, '女');
students[5] = new Student("刘亦菲", 36, 168, '女');
// 需求:按照身高升序排序。可以调用sun公司写好的API直接对数组进行排序。
Student t = new Student();
// Arrays.sort(students, (o1, o2) -> t.compareByHeight(o1, o2));
// 实例方法引用:对象名::实例方法
// 前提:-> 前后参数的形式一致,才可以使用实例方法引用
Arrays.sort(students, t::compareByHeight);
// 遍历数组中的学生对象并输出
for (int i = 0; i < students.length; i++) {
Student s = students[i];
System.out.println(s);
}
}
}
7.11特定方法引用
import java.util.Arrays;
public class Demo3 {
public static void main(String[] args) {
// 目标:特定类型的方法引用。
// 需求:有一个字符串数组,里面有一些人的名字都是,英文名称,请按照名字的首字母升序排序。
String[] names = {"Tom", "Jerry", "Bobi", "曹操" , "Mike", "angela", "Dlei", "Jack", "Rose", "Andy", "caocao"};
// 把这个数组进行排序:Arrays.sort(names, Comparator)
// Arrays.sort(names); // 默认就是按照首字母的编号升序排序。
// 要求:忽略首字母的大小进行升序排序(java官方默认是搞不定的,需要我们自己指定比较规则)
// Arrays.sort(names, new Comparator<String>() {
// @Override
// public int compare(String o1, String o2) {
// // o1 angela
// // o2 Andy
// return o1.compareToIgnoreCase(o2); // java已经为我们提供了字符串按照首字母忽略大小写比较的方法:compareToIgnoreCase
// }
// });
// Arrays.sort(names, (o1, o2) -> o1.compareToIgnoreCase(o2) );
// 特定类型方法引用:类型名称::方法名
// 如果某个Lambda表达式里只是调用一个特定类型的实例方法,并且前面参数列表中的第一个参数是作为方法的主调,
// 后面的所有参数都是作为该实例方法的入参的,则此时就可以使用特定类型的方法引用。
Arrays.sort(names, String::compareToIgnoreCase);
System.out.println(Arrays.toString(names));
}
}
7.12构造器引用
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
public class Demo4 {
public static void main(String[] args) {
// 目标:理解构造器引用。
// 创建了接口的匿名内部类对象
// CarFactory cf = new CarFactory() {
// @Override
// public Car getCar(String name) {
// return new Car(name);
// }
// };
// CarFactory cf = name -> new Car(name);
// 构造器引用: 类名::new
CarFactory cf = Car::new;
Car c1 = cf.getCar("奔驰");
System.out.println(c1);
}
}
@FunctionalInterface
interface CarFactory {
Car getCar(String name);
}
@Data
@AllArgsConstructor
@NoArgsConstructor
class Car{
private String name;
}
7.13-ArrayList
import java.util.ArrayList;
public class ArrayListDemo1 {
public static void main(String[] args) {
// 目标:掌握ArrayList集合的基本使用。
// 创建ArrayList对象,代表一个集合容器
ArrayList<String> list = new ArrayList<>(); // 泛型定义集合。
// 添加数据
list.add("java");
list.add("java2");
list.add("java3");
list.add("赵敏");
System.out.println(list); // [java, java2, java3, 赵敏]
// 查看数据
System.out.println(list.get(0));
System.out.println(list.get(1));
System.out.println(list.get(2));
System.out.println(list.get(3));
System.out.println("-------------------------------");
// 遍历集合。
for (int i = 0; i < list.size(); i++) {
// i 0 1 2 3
String s = list.get(i);
System.out.println(s);
}
// 删除数据
System.out.println(list.remove(2)); // 根据索引删除
System.out.println(list);
System.out.println(list.remove("赵敏")); // 根据元素删除
System.out.println(list);
// 修改数据
list.set(0, "java4");
System.out.println(list);
}
}
7.14-String
import java.util.Scanner;
public class StringDemo1 {
public static void main(String[] args) {
// 目标:掌握创建字符串对象,封装要处理的字符串数据,调用String提供的方法处理字符串。
// 1、推荐方式一: 直接“”就可以创建字符串对象,封装字符串数据。
String s1 = "hello";
System.out.println(s1);
System.out.println(s1.length()); // 处理字符串的方法。
// 2、方式二:通过构造器初始化对象。
String s2 = new String(); // 不推荐
System.out.println(s2); // ""空字符串
String s3 = new String("hello"); // 不推荐
System.out.println(s3);
char[] chars = {'h','e','l','l','o',',','黑','马'};
String s4 = new String(chars);
System.out.println(s4);
byte[] bytes = {97, 98, 99, 65, 66, 67};
String s5 = new String(bytes);
System.out.println(s5);
System.out.println("========================================");
// 只有“”给出的字符串对象放在字符串常量池,相同内容只放一个。
String t1 = "abc";
String t2 = "abc";
System.out.println(t1 == t2);
String t3 = new String("abc");
String t4 = new String("abc");
System.out.println(t3 == t4);
System.out.println("========================================");
// 调用字符串的方法,处理字符串数据。
// 简易版的登录:
String okLoginName = "admin";
System.out.println("请您输入您的登录名称:");
Scanner sc = new Scanner(System.in);
String loginName = sc.next();
// 字符串对象的内容比较,千万不要用==,==默认比较地址,字符串对象的内容一样时地址不一定一样
// 判断你字符串内容,建议大家用 String提供的equals方法,只关心内容一样,就返回true,不关心地址。
if(okLoginName.equals(loginName)){
System.out.println("恭喜您,登录成功!");
}else{
System.out.println("登录失败!");
}
System.out.println("========================================");
// 18663656520 ==> 186****6520
System.out.println("请您用手机号码登录:");
String phone = sc.next(); // 18663656520
System.out.println("系统显示以下手机号码进入:");
String newPhone = phone.substring(0, 3) + "****" + phone.substring(7);
System.out.println(newPhone);
}
}
public class StringTest2 {
public static void main(String[] args) {
// 目标:生成验证码。
String code = getCode(4);
System.out.println(code);
System.out.println(getCode(6));
}
// 帮我生成指定位数的随机验证码返回,每位可能是大小写字母或者数字。
// 帮我用String变量记住全部要用到的字符。
public static String getCode(int n) {
// 1、定义一个变量记住所有字符。
String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
// 2、定义一个变量用于记住验证码的随机字符。
String code = "";
// 3、循环n次,每次生成一个随机字符,拼接成字符串。
for (int i = 0; i < n; i++) {
// 4、随机一个索引
int index = (int)(Math.random() * str.length()); // [0,1) * 50 = [0,49]
// 5、根据索引获取字符,拼接成字符串。
code += str.charAt(index);
}
// 6、返回验证码。
return code;
}
}
7.15-BorderLayout
import javax.swing.*;
import java.awt.*;
public class BorderLayoutExample {
public static void main(String[] args) {
JFrame frame = new JFrame("BorderLayout Example");
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JButton("North"), BorderLayout.NORTH);
frame.add(new JButton("South"), BorderLayout.SOUTH);
frame.add(new JButton("East"), BorderLayout.EAST);
frame.add(new JButton("West"), BorderLayout.WEST);
frame.add(new JButton("Center"), BorderLayout.CENTER);
frame.setVisible(true);
}
}
7.16-BoxLayout
import javax.swing.*;
public class BoxLayoutExample {
public static void main(String[] args) {
JFrame frame = new JFrame("BoxLayout Example");
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); // 垂直排列
panel.add(new JButton("Button 1"));
panel.add(Box.createVerticalStrut(10)); // 添加垂直间隔
panel.add(new JButton("Button 2"));
panel.add(Box.createVerticalStrut(10));
panel.add(new JButton("Button 3"));
panel.add(Box.createVerticalStrut(10));
panel.add(new JButton("Button 4"));
frame.add(panel);
frame.setVisible(true);
}
}
7.17-FlowLayout
import javax.swing.*;
import java.awt.*;
public class FlowLayoutExample {
public static void main(String[] args) {
JFrame frame = new JFrame("FlowLayout布局管理器");
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout()); // 设置布局管理器
frame.add(new JButton("Button 1"));
frame.add(new JButton("Button 2"));
frame.add(new JButton("Button 3"));
frame.add(new JButton("Button 4"));
frame.add(new JButton("Button 5"));
frame.setVisible(true);
}
}
7.18-GridLayout
import javax.swing.*;
import java.awt.*;
public class GridLayoutExample {
public static void main(String[] args) {
JFrame frame = new JFrame("GridLayout Example");
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(2, 3)); // 2行3列的网格
frame.add(new JButton("Button 1"));
frame.add(new JButton("Button 2"));
frame.add(new JButton("Button 3"));
frame.add(new JButton("Button 4"));
frame.add(new JButton("Button 5"));
frame.add(new JButton("Button 6"));
frame.setVisible(true);
}
}
7.19-JFrame
import javax.swing.*;
public class JFrameDemo1 {
public static void main(String[] args) {
// 目标:快速入门一下GUI Swing的编程。
// 1、创建一个窗口,有一个登录按钮。
JFrame jf = new JFrame("登录窗口");
JPanel panel = new JPanel(); // 创建一个面板
jf.add(panel); // 将面板添加到窗口中
jf.setSize(400, 300); // 设置窗口大小
jf.setLocationRelativeTo(null); // 设置窗口居中
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置关闭窗口的默认操作: 关闭窗口退出程序
JButton jb = new JButton("登录"); // 创建一个按钮
panel.add(jb); // 将按钮添加到面板中
jf.setVisible(true); // 显示窗口
}
}
7.20实战案例
import javax.swing.*;
import java.awt.*;
public class LoginUI {
public static void main(String[] args) {
JFrame frame = new JFrame("公司项目登录界面");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.setLocationRelativeTo(null); // 居中显示
// 设置背景颜色
frame.getContentPane().setBackground(new Color(245, 245, 245)); // 灰白色背景
// 创建面板
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(10, 10, 10, 10); // 内边距
gbc.fill = GridBagConstraints.HORIZONTAL;
// 标题标签
JLabel titleLabel = new JLabel("欢迎登录");
titleLabel.setFont(new Font("楷体", Font.BOLD, 24));
titleLabel.setForeground(new Color(64, 64, 64)); // 深灰色文字
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 2;
gbc.anchor = GridBagConstraints.CENTER;
panel.add(titleLabel, gbc);
// 用户名输入框
gbc.gridy++;
gbc.gridwidth = 1;
gbc.anchor = GridBagConstraints.LINE_START;
panel.add(new JLabel("用户名:"), gbc);
gbc.gridx++;
gbc.fill = GridBagConstraints.HORIZONTAL;
JTextField usernameField = new JTextField(20);
panel.add(usernameField, gbc);
// 密码输入框
gbc.gridy++;
gbc.gridx = 0;
gbc.fill = GridBagConstraints.NONE;
panel.add(new JLabel("密码:"), gbc);
gbc.gridx++;
gbc.fill = GridBagConstraints.HORIZONTAL;
JPasswordField passwordField = new JPasswordField(20);
panel.add(passwordField, gbc);
// 登录按钮
gbc.gridy++;
gbc.gridx = 0;
gbc.gridwidth = 2;
gbc.fill = GridBagConstraints.HORIZONTAL;
JButton loginButton = new JButton("登录");
loginButton.setBackground(new Color(0, 128, 255)); // 蓝色按钮
loginButton.setForeground(Color.WHITE);
loginButton.setFont(new Font("楷体", Font.BOLD, 14));
panel.add(loginButton, gbc);
frame.add(panel);
frame.setVisible(true);
}
}