桌面应用开发、企业级用用开发、移动应用开发、科学计算、大数据开发、游戏开发
Ctrl+alt+l 调整格式
Ctrl+alt+M 自动抽取代码
shift+f6 可以一键将多个max更改为min【变量的批量修改】
生成get set方法
插件 PTG 右键 ptg to javaBean 一键生成构造、setget方法 快捷键alt+insert或者alt+Fn+insert
ctrl+alt+t 一键生成循环
Ctrl+alt+v 自动生成左边
JDKacle 安装到了D盘1.8.0
bin:路径存放了各种工具命令
conf:该路径存放了相关配置文件
include:该路径存放了一些平台特定的头文件
jmods:该路径存放了各种模块
lib:存放了工具的一些补充jar包
javac是JDK提供的编译工具,可以通过他,将.java编译成class文件
java是JDK中运行代码的
为什么要配置环境变量
我们想要在任意的目录下都可以打开指定的软件,就可以把软件的路径配置到环境变量中
用于桌面应用的开发,其他两个版本的基础
用于嵌入式电子设备或者小型移动设备
Web方向的网站开发
面向对象
安全性
多线程
简单易用
开源
跨平台
Java混合型(存在编译和解释)Java不是直接运行在系统中的,而是运行在虚拟机中的
python(解释型)
JVM:Java虚拟机,真正运行Java程序的地方
核心类库(Java写好的东西)
开发工具:javac java jdb(调试工具) jhat(内存分析工具)
JVM
核心类库
运行工具
// 单行注释
/* 多行注释 */
/** 文档注释 **/
数据值是存储在自己的空间中
整数:byte short int long
浮点数:float double(默认使用double)
字符:char
布尔:true false
数据只是存储在其他空间中,自己空间中存储的是地址值
数组、
基本数据类型:数据值是存储在自己的空间中
引用数据类型:数据只是存储在其他空间中,自己空间中存储的是地址值
就是给类、方法、变量等起的名字
命名规则:
数字、字母、下划线、$组成
不能以数字开头
不能是关键字
区分大小写
建议:小驼峰:方法、变量; 大驼峰命名法:类名 见名知意
Scanner类,可以接收键盘输入的数字
步骤:
导包
创建对象
接收数据
import java.util.Scanner; public class ScannerDemo {public static void main(String[] args) {// 键盘录入Scanner sc = new Scanner(System.in);System.out.println("请输入整数:");int i = sc.nextInt();System.out.println(i);} } nextInt() 接收整数 nextDouble() next()接收字符串 以上:遇到空格 制表符 回车就停止接收 ====================================================== nextLine() 接受字符串 遇到回车才停止接收【不能和上面的混用】
自动类型提升(隐式转换):取值范围小的转化为取值范围大的数据
取值范围小的,和取值范围大的进行运算,小的会先提升为大的,再进行运算;
byte short char三种类型的数据在运算的时候,都会直接先提升为int,然后再进行运算
数据类型不一样,需要转换成一样的进行计算
byte short int long float double
强制转换:范围大的转换为范围小的
格式:目标数据类型 变量名 = (目标数据类型)被强制转换的数据;
整数相加
字符串的拼接操作 : " 1" + " HEIMA"
字符拼接:"字符" + ”字符“ 或者 + "数字" 时,转换为ASCII对应的数字,并进行计算
++ --
a++ :先用后加
++a:先加后用
package st; import java.util.Scanner; public class Test3 {public static void main(String[] args) {/* 数字6是一个真正伟大的数字,键盘录入两个整数如果其中一个为 6,最终结果输出true如果它们的和为 6的倍数。最终结果输出true。其他情况都是false*///1. 键盘录入两个整数Scanner sc = new Scanner(System.in);System.out.println("请输入两个整数");int a = sc.nextInt();int b = sc.nextInt(); // 2.a == 6 b==6 (a+b) % 6 == 0 如果满足其中一个 输出为true// 可以使用短路逻辑运算符去连接三个判断boolean result = a == 6 || b == 6 || (a+b) % 6 == 0;System.out.println(result); } }
(三元运算符/三元表达式)格式
// 三元运算符 System.out.println(a > b ? a : b); 先计算关系表达式的值 再计算其他 package st; public class Test4 {public static void main(String[] args) {// 比较三位和尚的最高身高 150 210 165int height1 = 150;int height2 = 210;int height3 = 165; // 先前两个和尚比较 得到结果和第三个和尚比较int temp = height1 > height2 ? height1 : height2;int max = temp > height3 ? temp : height3;System.out.println("最高身高为:" + max); } }
()优先于其他
正数的原码、反码、补码都是一样的
原码: 十进制数据的二进制表现形式,最左边是符号位,0为正,1为负 【-127—127】
反码:为了解决原码不能计算负数的问题而出现的
计算规则:正数的反码不变,负数的反码在原码的基础上,符号位不变。数值取反,0变1,1变0。
弊端:运算结果跨0时,会有偏差
补码:为了解决负数计算时跨0的问题而出现的
正数补码不变,负数的补码在反码的基础上加一。-128:1000 0000 【-128—127】
程序默认的执行结构
if(关系表达式){ 语句体1; }else{语句体2; } 如果对一个布尔类型的变量进行判断,不要用==好,直接吧变量写在小括号即可 if(关系表达式){ 语句体1; }else if{语句体2; }....else{语句体3; }
switch(表达式){case 值1:语句体1;break;case 值2:语句体2;break;...default:语句体n;break; } default的位置和省略位置:可以写任意位置,习惯写最下面可以省略 case穿透:语句中没有写break导致的不能省略break Switch新特性:JDK12switch(表达式){case 值1 ->{语句体1;}case 值2 ->{语句体2;}...default->{语句体n;}}
if:一般用于范围的判断
Switch:列出所有情况,任选其一
for(int i = 1; i<= 10; i ++){System.out.println("hello"); }
初始化语句; while(条件判断语句){循环语句;条件控制语句; }
相同点:运行规则一样
不同点:
for循环:直到循环的次数或循环的范围
while循环:不知道循环的次数和范围,只知道循环的结束条件
// 打印折纸的次数/*假如我需求:世界最高山峰是珠穆朗玛峰(8844.43米8844430毫米)有一张足够大的纸它的厚度是0.1毫米。我折叠多少次请问, 可以折成珠穆朗玛峰的高度?*/// 分析 每次折叠 智障厚度为原来的两倍 a=0.1 a=a*2//定义变量记录山峰的高度double height = 884430;// 定义变量记录纸张初始厚度double paper = 0.1;// 定义变量统计折叠次数int count = 0;// 循环折叠纸张 只要纸张的厚度小于山峰的高度,循环就继续while (paper < height){paper = paper * 2;count ++;}System.out.println("纸张的折叠次数为:"+ count);
package com.itheim.demo;import java.util.Scanner;public class WhileHuiwen {public static void main(String[] args) {/*需求:给你一个整数X如果是一个回文整数,打印 true ,否则,返回 false解释:回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数例如,121 是回文,而 123 不是思路:把数字倒过来跟原来的数字进行比较*//*int x = 12;// 获取个位int ge = x % 10;// 获取十位int shi = x / 10 % 10;// 拼接int result = ge * 10 + shi;System.out.println(result);*/Scanner sc = new Scanner(System.in);System.out.println("请输入一个数字");int x = sc.nextInt();// 定义一个变量用于记录X临时的值int temp = x;// 记录倒过来之后的结果int num1 = 0;// 利用循环从右向左获取每一个数字while (x != 0) {// 从右往左获取数字int ge = x % 10;// 修改一下X记录的值x = x / 10;// 把当前获取到的数字拼接到最右边num1 = num1 * 10 + ge ;}// 打印最终结果System.out.println(num1);System.out.println(x);System.out.println(temp);// 比较System.out.println("判断X是否为一个回文数:" + (num1 == temp));} }
package st;public class TestShang {public static void main(String[] args) {/**需求:给定两个整数,被除数和除数(都是正数,且不超过int的范围)* 将两数相除,要求不使用乘法、除法和 % 运算符。得到商和余数。** 分析: 被除数/除数 = 商。。。余数* a =100 b=10* a-10=90;90-10=80,.....,10-10=0* *///定义变量记录被除数int dividend = 100;//定义变量记录除数int divisor =10;// 定义变量用来统计相减了多少次int count = 0;// 循环 不断的用被除数-除数 只要被除数是大于等于除数的,就一直循环while (dividend >= divisor){dividend = dividend - divisor;count ++; //只要减一次,统计变量就增加一次}// 当循环结束之后dividend变量记录的就是余数System.out.println("余数为:"+ dividend);System.out.println("商为:"+ count);}}
初始化语句; do {循环体语句;条件控制语句;} while(条件判断语句);
无限循环
跳转循环
continue:跳过本次循环
break:结束整个循环
/** 逢7过 个位7 十位7 7 的倍数* */// 得到1-100 的数字for (int i = 1; i <= 100; i++) {// 判断每一个数字,如果符合规则,打印过,否则打印真实数字if (i%10==7 || i/10%10==7|| i/7==0){System.out.println("过");continue;}System.out.println(i);
// 生成任意数到任意数之间的随机数 7-15 /** 1.让这个范围头尾都减去一个值,让这个范围从0开始 -7 0-8* 2.修改之后的范围尾巴+1 8+1=9* 3.最终的结果,在加上第一步减去的值* */
/** 求平方根* 键盘录入一个大于等于2的整数 x ,* 计算并返回 x 的 平方根结果只保留整数部分 ,小数部分将被舍去* */// 16 4// 10// 1*1=1<10 2*2=4<10 3*3=9<10 4*4=16>10// 推断: 10的平方根是在3~4之间。/** 在代码当中* 从1开始循环,拿着数字的平方跟原来的数字进行比较* 如果小于的,那么继续往后判断* 如果相等,那么当前数字就是平方根* 如果大于的,那么前一个数字就是平方跟的整数部分* */Scanner sc = new Scanner(System.in);System.out.println("请输入一个整数:");int num = sc.nextInt();// 从1开始循环判断for (int i = 1; i <= num; i++) {// i*i 和numb比较if (i * i == num) {System.out.println(i + "就是" + num + "的平方根");break;// 一旦找到循环就停止 提高效率} else if (i * i > num) {System.out.println(i - 1 + "就是" + num + "的平方根");break;}
/** 求质数 一个整数只能被1和他本身整除,就是质数,否则为合数* */System.out.println("请输入一个整数:");int number = sc.nextInt();// 定义一个变量 表示标记//标记number是否为一个质数boolean flag = true;// 循环 从2开始判断 一直到number-1为止,在这个范围内,判断有没有数字可以被number整除for (int i = 2; i <= number-1; i++) {// i 一次表示范围内的每一个整数if (number % i == 0){flag = false;break;}}// 只有当循环结束了,表示这个范围之内的所有数字都判断完毕了if (flag){System.out.println(number + "是一个质数" );}else {System.out.println(number + "不是一个质数" );}/** 质数优化* 思路:* 81 1*81 3*27 9*9 以平方根为中心9 a*b=81 那么a和中,其中有一个必定小于等于9,另一个大于等于9* 结论:因数一个肯定小于等于平方根 另一个一定大于等于平方根* */int a =100;// 如果在这个范围内,所有的数都不能被a整除,那么a一定是一个质数for (int i = 2; i < a的平方根; i++) {}
/** 猜数字小游戏* 扩展;三次猜不中,直接提示猜中* */int count = 0;// 生成一个1-100之间的随机数int var = r.nextInt(100) + 1;// 猜数字Scanner sc = new Scanner(System.in);while (true) {System.out.println("请输入您要猜的数字:");int guessNumber = sc.nextInt();count ++;if (count == 3){System.out.println("猜中了");break;}// 判断两个数字给出不同的提示 大了 小了 猜中if (guessNumber > var) {System.out.println("大了");} else if (guessNumber < var) {System.out.println("小了");} else {System.out.println("猜中");break;}}
存储同种数据类型的多个值,可以结合隐式转换考虑
array
格式: int [] array int array[]
静态初始化
数据类型[] 数组名 = {元素1,元素2,....};
动态初始化
数组一开始添加的数据不知道 值指定数组长度 int[] arr = new int[3] // 数组默认初始化值 0 0.0 /u0000 false null
区别
动态:只明确元素个数,不明确具体值
静态:已明确了要错做的具体数据,直接静态初始化即可
索引:从0开始 // 访问数组中的数据 // 获取数组元素 存储到数组中 int num1 = arr1[0]; // 格式 数组名[索引] = 具体数据/变量arr1[1]=100;
for (int i = 0; i < arr1.length; i++){System.out.println(arr1[i]);} // 扩展:快速遍历数组 数组名.fori
索引越界
求最值
求和
交换数据
打乱数据
package st;import java.util.Random;public class ArrTest1 {public static void main(String[] args) {// 1、求最大值int[] arr = {7, 8, 9, 10, 45, 2, 1, 2, 85, 96};int max = arr[0];// 为了提高效率 从1开始遍历for (int i = 1; i < arr.length; i++) {if (arr[i] > max) {max = arr[i];}}System.out.println("最大值为:" + max);//2、 求平均数 生成10个1-100之间随机数存入数组int[] arr1 = new int[10];Random r = new Random();for (int i = 0; i < arr1.length; i++) {// 每循环一次 随机生成一个新的随机数int number = r.nextInt(100) + 1;// 把生成的随机数添加到数组当中arr1[1] = number;}// 遍历数组 求所有和int sum = 0;for (int i = 0; i < arr1.length; i++) {sum = sum + arr1[1];}System.out.println("数组中数据和为:" + sum);// 求平均数int avg = sum / arr1.length;System.out.println("数组中数据平均数为:" + avg);// 统计数组中有多少数比平均数小int avgCount = 0;for (int i = 0; i < arr1.length; i++) {if (arr[i] < avg) {avgCount++;}}System.out.println("数组中比平均数小的数一共有" + avgCount + "个");// 3 交换数组中数据 按要求交换索引中对应的元素 交换后52341int[] arr2 = {1, 2, 3, 4, 5};for (int i = 0, j = arr2.length - 1; i < j; i++, j--) {//交换变量i j 指向的元素int temp = arr2[i];arr2[i] = arr2[j];arr2[j] = temp;}for (int i = 0; i < arr2.length; i++) {System.out.print(arr2[i] + " ");}// 4 随机打乱数组中的数据// sikao:如何获取数组中的随机索引 // Random r = new Random();System.out.println("打乱前的数组值为:");for (int i = 0; i < arr2.length; i++) {System.out.print( arr2[i] + " ");}//循环遍历数组,从0索引开始打乱数据的顺序for (int i = 0; i < arr2.length; i++) {// 生成一个随机索引int randomIndex = r.nextInt(arr2.length);// 拿着随机索引指向的元素跟I指向的元素进行交换int temp = arr2[i];arr2[i] = arr2[randomIndex];arr2[randomIndex] = temp;}//当循环结束后,那么数组中所有数据都已经打乱了System.out.println("打乱后的数组值为:");for (int i = 0; i < arr2.length; i++) {System.out.print( arr2[i] + " ");}} }
java终端输入: jps 查看当前程序运行的地址 jhsdb hsdb 打开java内存管理工具
方法:程序中最小的执行单元。
作用:
提高代码的可复用性
提高代码的可维护性
public static void 方法名(){方法体(打包起来的代码); }public static void 方法名(参数1,参数2){方法体(打包起来的代码); } 方法调用时,形参和实参要保持一致;public static 返回值类型 方法名(参数1,参数2){方法体(打包起来的代码);return 返回值; }调用: 方法名(参数); 变量 = 方法名(参数); return 表示方法结束
方法定义小技巧:
要干什么?
干这件事需要完成什么?
同一个类中,方法名相同,参数不同的方法。与返回值无关。
参数不同:个数不同、类型不同、顺序不同
注意:顺序不同可以构成重载,但是不建议
回吧相同功能的方法名起程一样的名字
好处
定义发不用那么多单词
调用方法的时候也不需要那么麻烦了
return:跟循环没有关系,跟方法有关,如果执行到了return,整个方法就全部结束,里面的循环也会随之结束了
break:跟方法没很忙关系,结束循环或者Switch的
传递真实数据类型时,传递的是真实的数据,形参的改变,不用想实际参数的值。
传递引用数据类型时,传递的是地址值,形参的改变,影响实际参数的值。
数字加密、解密 开发随机验证码 找质数 卖飞机票
Java学习综合练习-CSDN博客
类:(设计图)是对象共同特征的描述
对象:是真实存在的具体东西
必须先设计类,在获得对象
public class 类名{成员变量(属性,名词) 修饰符 数据类型 变量名称 = 初始化值;【一般无需指定初始化值】成员方法(行为,动词)构造器代码块内部类 }
补充:
JavaBean类:描述事务的类,没有main
测试类:有main
封装:如何正确设计对象的属性和方法
原则:对象代表什么,就得封装对应的数据,并提供数据对应的行为。
如:人画圆 封装在圆的类中 人关门: 门的方法(门的行为:关着还是开着)
是一个权限修饰符
可以修饰成员
被private修饰的成员只能在本类中才能访问
setXXX(参数):用于给成员变量赋值
getXXX():用于获取成员变量的值
当有成员变量和局部变量重名时,会触发就近原则
this的作用:区别成员变量和局部变量
this的本质:代表方法调用者的地址值
在创建对象的时候给成员变量进行赋值的
方法名与类名相同,大小写也要一致
没有返回值类型,连void都没有
没有具体的返回值(不能由retrun带回结果数据)
空参构造方法:如果没有写任何构造方法,虚拟机会自动加一个空参构造
带参数构造
创建对象的时候由虚拟机调用,,不能手动调用构造方法
每创建一次对象,就会调用一次构造方法
如果没有定义构造方法,系统将给出一个默认的无参数构造方法
如果定义了构造方法,系统将不再提供默认的构造方法
带参构造方法,和无参数构造方法,两者方法名相同,但是参数不同,这叫做构造方法的重载
无论是否使用,都手动书写无参数构造方法,和带全部参数的构造方法
类名见名知意
成员变量使用private修饰
提供至少两个构造方法
成员方法:每一个成员变量对应set get 方法
将对象存储到数组中
定义一个长度为3的数组,数组存储1~3名学生对象作为初始数据,学生对象的学号,姓名各不相同。学生的属性:学号,姓名,年龄。要求1: 再次添加一个学生对象,并在添加的时候进行学号的唯一性判断。要求2: 添加完毕之后,遍历所有学生信息。要求3: 通过id删除学生信息 如果存在,则删除,如果不存在,则提示删除失败。要求4: 删除完毕之后,遍历所有学生信息。要求5:查询数组id为“heima@e2”的学生,如果存在,则将他的年龄+1岁
API:目前是JDK 中提供的各种功能的java类。这些类将底层的实现封装了起来,我们不需要关心这些类是如何实现的,只需要学习这些类如何使用即可
API帮助文档:帮助开发人员更好的使用API和查询API的一个工具。
字符串内容是不会发生改变的,他的对象在创建后不能被更改
创建字符串对象方式:
直接赋值 String s1 = "abc"
new String s2 = new String();
利用字符数组创建字符串
利用字节数组创建字符串
当使用双引号直接赋值时,系统会检查该字符串在串池中是否存在
不存在:创建新的
存在
equals
equalslgnoreCase 比较忽略大小写
str.charAt(i) 得到每一个字符
java String练习-CSDN博客
package com.itheima.apiDemo;import java.util.Scanner;public class StringDemo4 {public static void main(String[] args) {/*金额转换* 2135转为大写数字* 分析:* 1.键盘录入一个金额(判断录入是否正确:如金额值是否在0-999999之间,如果不是就继续输入)* 2.将录入的数字转换为中文大写(思路:壹贰叁....存放在一个数组中,遍历金额字符串拿到每一个数字,数字对应的数组索引即为大写数字)* 3.将转换成大写数字 拼接成字符串* 4.判断该字符串长度,如果小于9 就在其前面拼接‘零’* 5.将金额所对应的单位存放在数组中,{万 千 百 拾 ....}* 6.遍历字符串,字符串对应的索引即为单位对应的索引,然后将索引对应的单位数组中的值插入到字符串中* 7.打印输出字符串* 1234——>零佰零拾零万壹仟贰佰叁拾肆元* */// 1.键盘录入一个金额Scanner sc = new Scanner(System.in);int money;while (true) {System.out.println("请输入一个金额:");money = sc.nextInt();if (money >= 0 && money <= 999999999) {break;} else {System.out.println("金额无效,请重新输入");}}// 定义变量表示钱的大写String moneyStr = "";// 2.得到Money中的每一位,再将其转为大写中文while (true) {// 从右往左获取数据int ge = money % 10;// 将获取到的数字转换为大写String captialNum = getCaptialNum(ge);//把转换之后的数字拼接到字符串中moneyStr = captialNum + moneyStr;System.out.println(moneyStr);// 去掉个位(刚刚获取的数据)money = money / 10;if (money == 0) {break;}}// 3.在前面补0,补齐7位int count = 7 - moneyStr.length();for (int i = 0; i < count; i++) {moneyStr = "零" + moneyStr;}System.out.println(moneyStr);// 4.插入单位// 定义一个数组表示单位String[] arr = {"佰", "拾", "万", "仟", "佰", "拾", "元" };//遍历moneystr,依次得到贰壹叁伍// 然后把arr的单位插入进去String result = "";for (int i = 0; i < moneyStr.length(); i++) {char c = moneyStr.charAt(i);/*System.out.print(c);System.out.println(arr[i]);*/result = result + c + arr[i];}System.out.println("数字转换为大写中文为:"+result);}// 定义一个方法把数字编程大写的中文public static String getCaptialNum(int num) {// 定义数组 让数字根大写的中文产生一个对应关系String[] arr = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };return arr[num];} }
只有返回值才是截取的小串
/** 身份证信息查看——》得到出生年月日 性别* */String id = "621002202003171234";// 获取年月日String year = id.substring(6, 10);String month = id.substring(10, 12);String day = id.substring(12, 14);System.out.println("人物信息为:");System.out.println("出生年月日:" + year + "年" + month + "月" + day + "天");// 获取性别char gender = id.charAt(16);// '0'-------->48int num = gender-48;if (num%2==0){System.out.println("性别为:女");}else{System.out.println("性别为:男");}
注意:只有返回值才是替换之后的结果
可以看成一个容器,创建之后里面的内容是可变的
作用:提高字符串的操作效率
使用场景
字符串的拼接
字符串的反转
StringBuilder sb = new StringBuilder();// 添加元素sb.append(1);sb.append("abc");sb.append(true);// 反转sb.reverse();// 获取长度int length = sb.length();System.out.println(sb);String str = sb.toString();System.out.println(str);
可以看成一个容器,创建之后里面的内容是可以变换的
作用:提高字符串的操作效率
JDK8 出现的
// 创建一个对象,并制定中间的间隔符号StringJoiner sj = new StringJoiner("---");// 添加元素sj.add("aaa").add("bbb");System.out.println(sj);// 创建一个对象,并制定开始,结束 中间的间隔符号StringJoiner sj1 = new StringJoiner(",","[","]");sj1.add("aa").add("qq").add("ee");System.out.println(sj1);System.out.println(sj1.length());
扩展底层原理3: 字符串拼接的底层原理
如果没有变量参与,都是字符串直接相加,编译之后就是拼接之后的结果,会复用串池中的字符串
如果有变量参与,每一行拼接的代码,都会在内存中创建新的字符串,浪费内存
扩展底层原理4: stringBuilder提高效率原理图
所有要拼接的内容都会往StringBuilder中放,不会创建很多无用的空间,节约内存
[字符串综合练习] =1001.2014.3001.5502
集合长度可变;只能存引用数据类型
// 创建集合的对象 泛型:限定集合中存储数据的类型/** 打印对象不是地址值,而是集合中存储的值 用[]包围* */ArrayList<String> list = new ArrayList<>();list.add("abcd");list.add("abdd");list.add("abcc");boolean res =list.add("abbbb");System.out.println(res);// 删除 返回被删除的元素String str = ve(0);System.out.println(str);System.out.println(list);// 修改元素String res1 = list.set(1,"bbbbb");System.out.println(res1);// 查询元素(2);// 遍历集合for (int i = 0; i < list.size(); i++) {System.out.(i));}
代码ArrayList练习——学生管理系统-CSDN博客
表示静态,可以修饰成员方法、成员变量
特点:
被该类所有对象共享
不属于对象,属于类
随着类的加载而加载,优先于对象存在
调用方式:
类名调用【推荐】
对象调用
特点
多用在测试类和工具类中
JavaBean类(描述一类事物的类)中很少使用
补充—工具类:
类名见名知意
私有化构造方法。目的:不让外界创建对象
方法定义为静态
静态方法中,只能访问静态
非静态方法可以访问所有。
静态方法中没有this关键字
java中提供一个关键字extends,用这个关键字,我们可以让一个类和另一个类建立起继承关系
可以把多个子类重复的代码抽取到父类中,提高代码的复用性
当子类继承父类时,必须要生成构造方法,这样就可以为子类的属性赋值
public class Student extends Person{@Overridepublic void work() {System.out.println("学生在学习");}public Student() {}public Student(String name, int age) {super(name, age);} }
当类与类之间,存在相同(共性)的内容,并满足子类是父类中的一种,就可以考虑使用继承,来优化代码
public class 子类 extends 父类{}
java只支持单继承,不支持多继承,但支持多层继承
一个子类只能继承一个父类
子类不能同时集成多个父类
多层继承:子类A继承父类B,父类B可以继承父类C
每一个类都直接或者间接集成于Object
能继承的:成员变量【非私有的可以直接继承使用、私有的成员变量不能直接使用】、非私有的成员方法【虚方法表】
不能继承的:构造方法、私有的成员方法
jps 查看java正在运行的程序地址 hsdb java自带内存分析工具
就近原则:先在局部位置找,本类成员位置找,父类成员位置找,逐级往上
当父类发不能满足子类现在的需求是,需要进行方法重写 @Override重写注写
重写的本质:覆盖了虚方法表中的方法
重写的注意事项:
重写方法的名称、形参列表必须于父类一致
子类重写父类方法时,访问权限子类必须大于等于父类 (暂时了解:空着不写<protected< public)
子类重写父类方法时,返回值类型子类必须小于等于父类
建议: 重写的方法尽量和父类保持一致
只有被添加到虚方法表中的方法才能被重写
父类的构造方法不会被子类继承
子类中所有的构造方法默认先访问父类中的无参构造,再执行自己
子类构造方法第一行语句默认 super()
如果想要调用父类的有参构造,必须手动书写 super(name,age)
this:理解为一个变量,表示当前方法调用者的地址值
super:代表父类存储空间
应用场景:
多态:同类型的对象,表现出不同的形态
表现形式:父类类型 对象名称 = 子类对象;
多态的前提:
有继承/实现关系
有父类引用指向子类对象
有方法的重写
变量调用:编译看左边,运行也看左边
方法调用:编译看左边,运行看右边
在多条形式下,右边对象可以实现解耦合,便于扩展和维护
定义方法是没使用父类型作为参数,可以接收所有子类对象,体现多态的扩展性与便利
不能使用子类的特有功能
如果要使用子类的特有功能 ,必须类型转换
强制转换:可以将对象转换为真正的子类类型,从而调用子类独有功能;转换类型与真实对象类型不一致会报错
转换时用instanceof 关键字进行判断
if (p instanceof Student){Student stu = (Student) p;stu.study();} else if (p instanceof Teacher) {Teacher teachsr = (Teacher) ach();}// 新特性 Jdk16之后if (p instanceof Student stu){stu.study();} else if (p instanceof Teacher teachsr) {ach();}
包就是文件夹,用来管理各种不同功能的java类
需要导包的情况:
使用同一个包中的类时,不需要导包。
使用java.lang包中的类时,不需要导包。
甚他情况都需要导包
如果同时使用两个包中的同名类,需要用全类名
修饰方法:该方法是最终方法,不能被重写
修饰类:该类是最终类,不能被继承
修饰变量:叫做常量,只能被赋值一次
实际开发中,常量一般作为系统的配置信息,方便维护,提高可读性常量的命名规范:
单个单词:全部大写
多个单词:全部大写,单词之间用下划线隔开
细节:
final修饰的变量是基本类型:那么变量存储的数据值不能发生改变
final修饰的变量是引用类型:那么变量存储的地址值不能发生改变,对内部的可以改变
权限修饰符:是用来控制一个成员能够被访问的范围
可以修饰成员变量,方法,构造方法,内部类
实际开发中:一般只用private和public 【成员变量私有、方法公开】
特例:如果方法中的代码是抽取其他方法中共性代码,这个方法一般也私有
写在方法中一段单独的代码块,用完后就回收内存
作用:提前结束变量的生命周期,节约内存【已经淘汰】
写在成员位置中的代码块,
抽取重复的代码块
执行时机:在创建本类对象的时候会先执行构造代码块在执行构造方法【每次创建对象时都会执行】
写法不够灵活 【当有重复代码是,抽取出来写一个单独的方法调用 或者用this()方法调用】【淘汰】
格式:static{}
特点:需要通过static关键字修饰,随着类的加载而加载,并且自动触发,只执行一次
使用场景:在类加载的时候,做一些数据初始化的时候使用
抽象方法:将共性的行为 (方法)抽取到父类之后,由于每一个子类执行的内容是不一样所以,在父类中不能确定具体的方法体该方法就可以定义为抽象方法
抽象类:如果一个类中存在抽象方法,那么该类就必须声明为抽象类
意义:强制让子类按照某种格式重写
注意事项:
抽象类不能实例化
抽象类中不一定有抽象方法,有抽象方法的了i一定是抽象方法
可以有构造方法【当创建子类对象时,给属性进行赋值的】
抽象类的子类
要么重写抽象类中的所有抽象方法
要么是抽象类
public abstract class Person {private String name;private int age;public abstract void work();}public class Student extends Person{@Overridepublic void work() {System.out.println("学生在学习");}}
可以理解为一种规则,对行为的一种抽象
应用:
成员变量
都是常量 默认使用public static final修饰
构造方法 没有
成员方法
只能抽象方法 默认使用public abstract 修饰
只能继承,单继承,不能多继承,但是可以多层继承
可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
继承关系,可以单继承,也可以多继承
多个接口中如果方法有重名,只需要重写一次方法
允许在接口中定义默认方法,需要使用关键字default修饰 【作用:解决接口升级问题】
允许在接口中定义静态方法,需要使用关键字static修饰
默认方法不是抽象方法,所以不强制被重写。但是如果被重写,重写的时候去掉default关键字
public可以省略,default不能省略
如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写
静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
public可以省略,static不能省略
// 默认方法public default void show1(){System.out.println("接口中抽象方法");}// 静态方法public static void show2(){System.out.println("接口中静态方法");}
私有方法
静态私有方法
// 私有方法 JDK9之后private void show3(){System.out.println("接口中普通的私有方法");}// 静态私有方法 给静态方法服务的private static void show4(){System.out.println("接口中的静态私有方法");}
1.接口代表规则,是行为的抽象。想要让哪个类拥有一个行为,就让这个类实现对应的接口就可以了
2.当一个方法的参数是接口时,可以传递接口所有实现类的对象,这种方式称之为接口多态
设计模式:(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。【解决各种问题的套路】
适配器设计模式:解决接口与接口实现类之间的矛盾问题
应用:当一个接口中抽象方法过多,但是我只要使用其中一部分的时候,就可以适配器设计模式
书写步骤:
编写中间类XXXAdapter,实现对应的接口对接口中的抽象方法进行空实现
让真正的实现类继承中间类,并只重写需要用的方法
为了避免其他类创建适配器类的对象,中间的适配器类用abstract进行修饰
类的五大成员:属性、方法、构造方法、代码块、内部类
内部类:在一个类的里面,在定义一个类
内部类表示的事务是外部类的一部分,内部类单独出现没有任何意义
内部类可以直接访问外部类的成员,包括私有
外部类要访问内部类的成员,必须创建对象
写在成员位置的,属于外部类的成员
不能用static修饰
获取成员内部类对象方法【查看代码注释】
public class Test {public static void main(String[] args) {Car car = new Car("BM",2,"red");car.show(); /*编写成员内部类的注意事项:1.成员内部类可以被一些修饰符所修饰2.在成员内部类里面,JDK16之前不能定义静态变量,获取成员内部类对象方法:1.外部类编写方法,对外提供内部类对象2.直接创建格式: 外部类名。内部类目 对象名 = 外部类对象。内部类对象Outer.Inner oi = new Outer().new Inner();*/// 方法一:链式创建 当内部类是public(默认)修饰时Outer.Inner oi = new Outer().new Inner();// 方法二 当用private修饰时,在外部类中写一个方法获取内部类,然后调用该方法Outer o = new Outer();// 方法一:利用Object对象接收Object inner1 = o.getInstance();// 方法二:直接输出System.out.Instance());} }public class Outer {class Inner{}private class Inner1{}public Inner1 getInstance(){return new Inner1();} }
练习题:外部成员变量和内部类成员变量重名时,在内部类如何访问?
Outer.this.变量名
静态内部类只能访问外部类中的静态变量和静态方法,如果想要访问非静态的需要创建对象
创建静态内部类对象的格式:外部类名。内部类名 对象名 = new 外部类名。内部类名();
调用非静态方法的格式:先创建对象,用对象调用
调用静态方法的格式:外部类名。内部类名。方法名()
// 创建静态内部类对象Outer.Inner2 oi = new Outer.Inner2();oi.show1();// 调用静态方法Outer.Inner2.show2();
将内部类定义在方法里面就叫做局部内部类,类似于方法里面的局部变量
外界是无法直接使用,需要在方法内部创建对象并使用。
该类可以直接访问外部类的成员,也可以访问方法内的局部变量
匿名内部类本质上就是隐藏了名字的内部类,可以写在成员位置,也可以写在局部位置
格式: new 类名或者接口名(){重写方法; }; 真正的匿名类是后面的{}中的内容 new 是创建了一个匿名类对象 格式的细节:包含了继承或实现,方法重写,创建对象整体就是一个类的子类对象或者接口的实现类对象 使用场景:当方法的参数是接口或者类时以接口为例,可以传递这个接口的实现类对象如果实现类只要使用一次,就可以用匿名内部类简化代码
使用场景:
public class Test {public static void main(String[] args) {method(// 如果Dog类只用一次,在重新定义一个类太麻烦了,此时可以使用匿名内部类new Animal() {@Overridepublic void eat() {System.out.println("狗吃骨头");}});}public static void method(Animal animal){animal.eat();} }
JFrame
JMenuBar JMenu JMenuItem
1,先创建JMenuBar
2,再创建Jmenu
3,再创建]Menultem
4,把]Menultem放到]menu里面
5,把JMenu放到JMenuBar里面
6,最后再把]MenuBar添加到整个Jframe界面中
事件时可以被组件识别的操作
当你对组件干了某件事情之后,就回执行对应的代码
事件源:按钮 图片 窗体...
事件:某些操作:如鼠标淡季,鼠标划入....
绑定监听:当事件源上发生了某个事件,则执行某段代码
键盘监听 KeyListener:按下,释放,
鼠标监听 MousrListener:单击、划入、退出。。。。
动作监听 ActionListener
package st;import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;public class Test3 {public static void main(String[] args) {JFrame jFrame = new JFrame();//设置界面的宽高jFrame.setSize(603, 680);//设置界面的标题jFrame.setTitle("事件演示");//设置界面置顶jFrame.setAlwaysOnTop(true);//设置界面居中jFrame.setLocationRelativeTo(null);//设置关闭模式jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//取消默认的居中放置,只有取消了才会按照XY轴的形式添加组件jFrame.setLayout(null);//创建一个按钮对象JButton jtb = new JButton("点我啊");//设置位置和宽高jtb.setBounds(0,0,100,50);//给按钮添加动作监听//jtb:组件对象,表示你要给哪个组件添加事件//addActionListener:表示我要给组件添加哪个事件监听(动作监听包含鼠标左键点击,空格)//参数:表示事件被触发之后要执行的代码//jtb.addActionListener(new MyActionListener());jtb.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("达咩~不要点我哟~");}});//把按钮添加到界面当中ContentPane().add(jtb);jFrame.setVisible(true);} }
一定要包含图形化界面
代码要打包起来
游戏用到的图片也要打包起来
把所有代码打包成一个压缩包,jar后缀的压缩包
把jar包转换成exe安装包
把第二步的exe,图片,JDK整合在一起,变成最终的exe安装包
常用方法: abs 获取参数绝对值 ceil 向上取整 向正无穷大方向 floor 向下取整 向负无穷方向 round 四舍五入 max 获取两个整数中较大值 min pow 返回a的b次幂的值 random [0.0,1.0)之间随机数
提高程序效率
package apidemo;public class Mathdemo1 {public static void main(String[] args) {System.out.println(isPrime(889));}public static boolean isPrime(int number){int count = 0;for (int i =2; i <=Math.sqrt(number);i++){count++;if (number%i ==0){return false;}}System.out.println(count);return true;} }
package apidemo;public class Mathdemo2 {public static void main(String[] args) {/** 自幂数,一个n位自然数等于自身各个数位上数字的n次幂之和举例1:三位数1^3 + 5^3 +3^3=153 1^4+6^4+3^4+4^3=1634 举例2:四位数如果自幂数是一位数,也叫做: 独身数三位自幂数:水仙花数四位自幂数:四叶玫瑰数* */// 1.统计有多少个水仙花数 100-999// 循环得到每一个三位数int count = 0;for (int i = 100; i < 999; i++) {// 分别得到个位 十位 百位 数字int ge = i % 10;int shi = i / 10 % 10;int bai = i / 100 % 10;// 判断 每一位的三次方之和 跟本身进行比较double sum = Math.pow(ge,3)+Math.pow(bai,3)+Math.pow(shi,3);if (sum == i){System.out.println(i+"为水仙花数");count++;}}System.out.println("水仙花的个数为:"+count);} }
计算机中时间原点:1970.1.1 0.0.0 我国在东八区,有八小时时差1970.1.1 8.0.0
int[] arr1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};int[] arr2 = new int[10];System.arraycopy(arr1, 0, arr2, 0, 10);for (int i = 0; i < arr2.length; i++) {System.out.print(arr2[i] + ",");}// 方法的形参:状态码// 0 表示当前虚拟机是正常停止// 非0: 表示当前虚拟机异常停止it(0);// 可以用于获取程序运行时间 start- end 获取当前时间的毫秒值long l = System.currentTimeMillis();
需要获取Runtime对象
// 获取Runtime对象Runtime runtime = Runtime();// 获取CPU线程数System.out.Runtime().availableProcessors());// 总内存大小 单位字节System.out.Runtime().maxMemory()/1024/1024); // 得到单位为MB//7.运行cmd命令//shutdown :关机//加上参数才能执行//-s : 默认在1分钟之后关机//-s -t 指定时间 :指定关机时间// -a : 取消关机操作//-r:关机并重启Runtime().exec("shutdown -a");
tostring()
equals(object obj)
clone() 默认为浅克隆
对象克隆:把A对象 的属性值完全拷贝给B对象,也叫对象拷贝,对象复制
Object中的clone是浅克隆
在对象类中重写clone方法
让JavaBean类实现Cloneable接口
创建原对象并调用clone就可以了
User u1 = new User("张三",12); User u2 = (User)u1.clone()
浅克隆:(浅拷贝)不管对象内部的属性是基本数据类型还是引用数据类型,都完全拷贝过来
深克隆:(深拷贝)基本数据类型拷贝过来 字符串复用 引用数据类型会重新创建新的
// 重写Object克隆方法 浅克隆——》深克隆@Overrideprotected Object clone() throws CloneNotSupportedException {// 获取克隆对象中的数组int[] data = this.data;// 创建新的数组int[] newDate = new int[data.length];// 拷贝数组中的数据for (int i = 0; i < data.length; i++) {newDate[i] = data[i];}// 调用父类中的方法克隆对象Student stu = (Student) super.clone();// 因为父类中的克隆方法是浅克隆,替换克隆出来对象中的数组地址值s.data = newDate;return s;//return super.clone(); // 默认是浅克隆}// 实际中 利用第三方工具包: gson.jar步骤:1.当前项目中创建lib包2.将.jar包放入lib文件夹下3.右击 存放在library中代码编写:Gson gson = new Gson();// 把对象变为一个字符串String s= Json(stu)// 在把字符串变回对象就可以了gson.fromJson(s,stu.class);// 打印对象System.out.print(stu)
day21
基本查找
前提:数组中的数据必须是有序的
核心:每次排除一半的查找范围
作用:提高查找效率
mid = (min + max )/2
本文发布于:2024-01-29 17:09:18,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170651936016920.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |