-
【ALT+ / 】 内容补全 【Ctrl+ / 】 快速添加或取消行注释 【ctrl+shift+/ 】 【ctrl+shift+】添加/删除注释 【Ctrl+D】 删除当前行 【Ctrl+O】 显示大纲 【Ctrl + M 】 窗口最大化与还原 【Alt + Shift + R】 选中所需要重命名的类 【Ctrl+Shift+O】 快速地导入import 【ALT + SHIFT + Z】 添加try/catch语句块: 包围方式 【ALT + SHIFT + S】+ R 选择Getter and Setter
-
dir directory 查看当前文件夹下有多少文件及文件夹 cd.. 返回上一层目录 cd. 返回当前目录 md make directory 创建文件夹/目录 rd remove directory 移除文件夹/目录 cd/ 回到磁盘根目录 cd 回到磁盘根目录 del 文件名称 删除文件
-
特点一:面向对象 两个基本概念:类、对象 三大特性:封装、继承、多态 特点二:健壮性 吸收了C/C++语言的优点,但去掉了其影响程序健壮性的部分(如指针、内存的申请与释放等),提供了一个相对安全的内存管理和访问机制 特点三:跨平台性 通过Java语言编写的应用程序在不同的系统平台上都可以运行。
-
变量:存储数据的空间,计算机会给内存中的每一个变量分配一个内存地址,内存地址不便记忆,我们给变量取名 变量命名规则 变量名由字母、数字、下划线、美元符号$组成 变量名不能使用数字开头,不建议使用美元符号开头 变量名使用小驼峰命名法 变量命名要有意义,见名知意 不能使用Java关键字,Java中大概有50个关键字
-
基本数据类型(8个) 数值型 整型 byte、short、int、long 浮点型 float、double 非数值型 char(字符型)、boolean(true/false) 基本数据类型字节数 byte 1字节 short 2字节 int 4字节 long 8字节 float 4字节 double 8字节 char 2字节 boolean 注意: 在Java中小数默认是double类型,整数默认是int类型 因此 float num = 12.1F; double d = 12.1; char字符类型,char类型的数据类型要使用单引号''括起来,单引号中只能写1个字符 因此 char ch1= '1'; char ch2 = '男' boolean类型:boolean类型的数据只能是true或者false 因此 boolean bool = true; boolean bool2 = false; String类型:字符串类型,使用双引号括起来,双引号中给可以写任意多个字符 因此 String str = "hello world";
-
十进制转换成二进制 整数部分 将该数字不断除以2直到商为零,然后将余数由下至上依次写出,即可得到该数字的二进制表示 以将数字21转化为二进制为例 21 / 2 = 10....1 10 / 2 =5....0 5 / 2 =2....1 2 / 2 =1...0 1 /2 =0....1 所以结果是10101(从后往前写) 小数部分 利用小数部分乘2,取整数部分,直至小数点后为0 以数字0.625为例 0.625 * 2 = 1...0.25 0.25 *2 =0...0.5 0.5*2=1...0 将取得的数字从上到下写(101) 注意: 整数换成二进制不会产生问题,但小数转换成二进制,有可能永远不会余0,所以就会产生精度问题 例如 0.4永远不能准确换算成二进制 0.4 * 2 =0...0.8 0.8 * 2 =1...0.6 0.6 * 2 =1...0.2 0.2 * 2 =0...0.4(到了这一步又回去到第一步了) 即0110... (这四个二进制数无限循环,循环越多精度越高,只能无限接近0.4,但取不到0.4) 任何小于1并且大于-1的数对1取余,则结果就是小于1并且大于-1的数本身。包括0.4 0.4%1 = 0.4 1.4%1 = 0.3999999999999999 10.00-9.60 = 0.40000000000000036(这是因为9.60无法完全转换为2进制,所以就会导致转换后的数会比9.60小。最终的结果一定会大于0.4的) 10.4 %1 =
-
第一种方式:声名变量、给变量赋值分布写 声明变量:数据类型 变量名; 变量赋值:变量名 = 数据; int age; age=10; 第二种方式:声明变量、给变量赋值一步书写 数据类型 变量名 = 数据; short money = 199;
-
在声明变量前加上final,它就是一个常量 第一种方式:声名变量、给变量赋值分布写 声明变量:final 数据类型 变量名; 变量赋值:变量名 = 数据; final int AGE; AGE=10; 第二种方式:声明变量、给变量赋值一步书写 final 数据类型 变量名 = 数据; final short MONEY = 199; 注意 常量名通常大写 不同字符使用下划线分割 只能被赋值一次,通常定义时即对其初始化
-
赋值运算符 算术运算符 基本算术运算符 加 减 乘 除 取余 自增运算符(++) 自减运算符(--) 复合算术运算符 -= += *= /= %= 关系运算符(等于 不等于 大于 小于 大于等于 小于等于) 这个的结果是布尔类型,true或者false 等于和不等于的优先级小于后面四个的优先级 逻辑运算符(与或非) 这个的结果是布尔类型,true或者false 条件运算符(条件 ? 表达式1 : 表达式2) ----又叫三目运算符 如果条件为真,则执行第一个表达式,否则执行第二个表达式 int num1 = 100; int num2 = 101; int max =num1>num2?num1:num2; System.out.println("最大值:"+max); //输出值是num2 注意: 单目运算符包括 ! ++ --,优先级别高 优先级别最低的是赋值运算符 可以通过()控制表达式的运算顺序,()优先级最高 从右向左结合性的只有赋值运算符、三目运算符和单目运算符 算术运算符 > 关系运算符 > 逻辑运算符
-
相同点 运算规律是一样的,只有当&和&&左右两边同时为true的时候,&和&&的运算结果才为true 不同点 &&有短路功能:当&&左边表达式的结果为false,不再判断&&右边表达式的结果,直接输出&&运算结果 &没有短路功能:不管&左边表达的结果为true还是false,都要先去判断&右边表达式的结果,然后再输出&运算结果 相同点 运算规矩是一样的,只要|和||左右两边有一个为true,|和||的运算结果为true 不同点 ||有短路功能:当||左边表达式的结果为true,不再判断||右边表达式的结果,直接输出||运算结果 |没有短路功能:不管|左边表达式的结果为true还是false,都要去判断|右边表达式的结果,然后再输出|运算结果
-
自动类型转换规则 满足自动类型转换的两个条件 两种类型要兼容(数值类型(整形和浮点型)互相兼容) 目标类型大于源类型 double型大于int型 小容量向大容量转换,称为【自动类型转换】,不同类型的大小排序如下 byte < short (char) < int < long < float < double 例如: double d =10.0+10; 这个可以 int b = 10.0+10; 这个不可以 强制类型转换规则 大容量转换成小容量,要进行 【强制类型转换】 ,要加强制类型转换符,程序才能编译通过,但是在运行阶段可能导致精度损失 例如: int b =(int)10.2; 注意: 如采用+=、*=等缩略形式的运算符,系统会自动强制将运算结果转换为目标变量的类型。 short s1 =1; s1 += 1; //不能写成s1 = s1+1;会报错的
-
第一步:导入Scanner类(JDK中存在的,只需要导入就可以) import java.util.Scanner 第二步:创建Scanner对象 Scanner input = new Scanner(System.in); 第三步:获得键盘输入的数据 int now =input.nextInt();
//字符会根据ASCII表进行运算
//字符 3 对应的十进制是 51 字符 4 对应的十进制是52
char c1 = '3';
char c2 = '4';
System.out.println(c1+c2) 结果是103(51+52)
System.out.println(c1-c2) 结果是-1(51-52)
System.out.println(c1*c2) 结果是2652 (51*52)
System.out.println(c1/c2) 结果是0(51/52)
//同理
char c2='a';
char c3='b';
//字符a对应的十进制是97,字符b对应的十进制是98
2.条件运算符取最大值或者最小值
int num1 = 100;
int num2 = 101;
int max =num1>num2?num1:num2;
System.out.println("最大值:"+max);
//使用键盘录入两个整数,然后通过条件运算符进行比较,输出输入的两个值里面的最小值
//创建Scanner类对象
Scanner input =new Scanner(System.in);
System.out.println("请输入第一个整数:");
int firstNum=input.nextInt();
System.out.println("请输入第二个整数:");
int secondNum=input.nextInt();
int min =firstNum>secondNum?secondNum:firstNum;
System.out.println("你输入的两个数中最小的数是:"+min);
3.使用条件运算符输出3个数中的最大值
int a = 100; int b = 90; int c = 200; int max =a>b?(a>c?a:c):(b>c?b:c); System.out.println(max);4.&和&&运算符
int m = 8; int n = 9; int a = 8; int b = 9; System.out.println((++m!=n)&&(++m==n)); //当左边是false的时候,又因为它是一个&&运算(短路),所以不会计算右边的 System.out.println(m); //输出是9,不是10 System.out.println((++a!=b)&(++a==b)); //当左边是false的时候,因为它是一个&运算(不短路),所以会计算右边的 System.out.println(a); //输出是105.单目运算符先自增还是先赋值
int n= 100;
int m = n++;
System.out.println("n="+n); // n=101
System.out.println("m="+m); // m=100
int k =100;
int h = ++k;
System.out.println("k="+k); //k=101
System.out.println("h="+h); //h=101
6.获得四位数中的各个数字
Scanner input = new Scanner(System.in);
System.out.println("请输入一个四位数");
int count = input.nextInt();
int a1 = count%10; //个位
int a2 = count/10%10; //十位
int a3 = count/100%10; //百位
int a4 = count/1000; //千位
System.out.println("a1="+a1+" a2="+a2+" a3="+a3+" a4="+a4);
7.两个变量值交换(面试题)
//第一种方法:定义临时变量 int num1 =8; int num2=9; int temp; temp = num1; num1 = num2; num2 = temp; System.out.println(num1); System.out.println(num2); //第二种方法:利用位运算符实现两个变量值交换 int a = 10; int b =2; a = a^b; b = a^b; a = a^b; System.out.println(a); System.out.println(b); //第三种方法:利用加减法的操作 int a =1; int b =2; a = a+b; b = a-b; a = a-b; System.out.println(a); System.out.println(b);第二章 选择结构和循环结构 1.switch选择结构
-
switch(表达式){ case 常量值1: //代码语句; break; case 常量值2: //代码语句; break; case 常量值3: //代码语句; break; ......... default: //代码语句; break; 执行规律: 根据表达式的值,来与case后面的常量值进行匹配 匹配上哪个常量值,就执行该case里面的代码语句,代码语句执行完,执行break,退出整个Switch选择结构,执行Switch选择结构后面的代码 如果表达式的值与所有的case常量值不匹配,则执行default里面的代码语句,执行完执行break语句,退出整个Switch选择结构 注意事项: (1)表达式的值可以是int、short、byte、char、枚举类型、String(JDK7及以后版本可以使用) (2)case常量值不能相同 (3)default语句可以在任意位置,一般来说写在最后,也可以省略不写 (4)break的作用是结束整个Switch选择结构,如果不写,会造成“case穿透”现象,此现象可以合理使用
-
do{ 循环操作代码 迭代; }while(循环条件); 执行规律: (1)执行一次初始值代码 (2)先执行一次循环操作和迭代,然后判断循环条件是否满足,如果循环条件满足,则继续执行循环操作和迭代 (3) 如果循环条件不满足,则结束整个do-while循环结构,执行do-while循环结构后面的代码 注意: do-while循环结构,是先执行一次循环操作,再判断循环条件,也就是说do-while循环至少会执行一次循环操作 while循环结构,是先判断循环条件,再根据循环条件的结果决定是否执行循环操作,如果第一次循环条件就不能满足,循环操作就一次都不执行。
-
1. 初始值一定要声名才能使用,可以在for循环之上声名,也可以在for循环里声名 int i=0; for(; i<10;i++){ System.out.println("这是"+i); } 2.缺少循环条件,会进入死循环 for(int i=0;;i++) System.out.println("这是"+i); 3.缺少迭代部分,如果循环条件满足,会进入死循环.若在循环体中加入迭代部分,可以避免死循环 for(int i=0;i<10;){ System.out.println("这是"+i); i++ } 4.缺少初始值、循环条件、迭代部分,程序进入死循环 for(;;){ System.out.println("这是测试");
-
外层循环变化一次,内层循环变量变化一遍 外层循环控制行数,内层循环控制每一行的列数 for (int i = 1; i <= 3; i++) { //输出每一行前面的空格“ ” for (int j = 3-i; j >0; j--) { System.out.print(" "); } //输出每一行的“*” for (int k = 2*i-1; k >0; k--) { System.out.print("*"); } //换行 System.out.println(); } 输出内容 * *** *****
int j=2;
for(int i=2;i<100;i++){
for(j=2;j
if(i%j == 0){
break;
}
}
//当内层for循环完完全全执行一遍的时候,说明i多于小于i的所有正整数而言,不能整除,即它就是素数
if(i==j)
System.out.println(i);
}
2.判断一天是这一年的第几天
Scanner scanner = new Scanner(System.in);
System.out.print("请输入年: ");
int year= scanner.nextInt();
System.out.print("请输入月: ");
int month= scanner.nextInt();
System.out.print("请输入日: ");
int day= scanner.nextInt();
int result = 0;
if (month > 1) {
result += 31;
}
if (month > 2) {
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
result += 29;
} else {
result += 28;
}
}
if (month > 3) {
result += 31;
}
if (month > 4) {
result += 30;
}
if (month > 5) {
result += 31;
}
if (month > 6) {
result += 30;
}
if (month > 7) {
result += 31;
}
if (month > 8) {
result += 31;
}
if (month > 9) {
result += 30;
}
if (month > 10) {
result += 31;
}
if (month > 11) {
result += 30;
}
System.out.println(result + day);
3.假设有n瓶饮料,喝完3个空瓶可以换一瓶饮料,依次类推,请问总共喝了多少瓶饮料
System.out.println("请输入饮料总瓶数:");
Scanner sc = new Scanner(System.in);
int n =sc.nextInt(); //初始饮料总数
int count =n; //用于计算可以兑换多少瓶
int i=0; //兑换次数
while(true){
if(count<3){
System.out.println ("共喝了"+(n+i)+"瓶");
break;
}qw
count -= 3; //喝3瓶
count++; //兑换1瓶
i++; //兑换次数+1
}
4.求两个整数的最大公约数和最小公倍数
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
int y =sc.nextInt();
int m = gcd(x,y);
System.out.println("最大公约数是:"+m);
int n = x*y/m;
System.out.println("最小公倍数是:"+n);
//最大公约数
static int gcd(int a,int b){
if(b==0)
return a;
return gcd(b,a%b);
}
第三章 数组
1.一维数组
1.1.数组的定义
-
数组是一个变量,存储多个相同数据类型的一组数据
-
变量、数组和集合的区别 相同点: 都是装数据的容器 不同点: 声明一个变量就是在内存空间划出一块合适的空间,只能存储一个数据 声名一个数组就是在内存空间划出一串连续的空间,可以存储多个相同类型的数据 存储数据的空间,可以存储多个不同类型的数据
-
标识符:数组的名称,用于区分不同的数组 数组元素:向数组中存放的数据 元素下标(从0开始) 元素类型:数组元素的数据类型 注意: 数组长度固定不变,避免数组越界
-
1.数组声名 数据类型 数组名[]; 或者 数据类型[] 数组名;(最常用写法) 2.分配空间 数组名 = new 数据类型[数组长度]; 3.赋值 数组名[下标] = 数据; 注意:下标从0开始 例如: char[] c = {'1','2','3','4'}; 注意: 1和2可以合并写 数据类型[] 数组名 = new 数据类型[数组长度];(最常用写法)
-
byte/short/int/long 默认值0
float/dou ble 默认值0.0
char 默认值" "
boolean 默认值 false
String 默认值 null
-
数据类型[] 数组名 = new 数据类型[]{数据1,数据2,....,数据n}; 或者 数据类型 数组名[] = new 数据类型[]{数据1,数据2,....,数据n}; -
声明数组、分配空间、赋值合并写的简写如下: 数据类型[] 数组名 ={数据1,数据2,....,数据n}; 或者 数据类型 数组名[] ={数据1,数据2,....,数据n};(最常用的一种方法) -
注意: 这里长度是不用写的,否则会报错
-
Arrays类:操作数组的工具类,该类中提供了很多操作数据的方法 先导入Arrays包 1.Arrays.sort(数组名); 可以使用Arrays类的sort()方法对数组中的数据进行升序排序 2.Arrays.toString(数组名); 将一个数组转换成一个字符串 int nums = {1,2,3,4,5}; String str = Arrays.toString System.out.println(str); 输出的字符串是 [1,2,3,4,5] 3.Arrays.equals(arr1,arr2) 比较两个数组是否相同,两个元素的个数,内容,元素顺序完全相同为true,否则一个不同就是false 4.Arrays.fill(数组名,数值); 将数组中的所有元素替换成你指定的数值 int nums1 = {11,12,13,14,15}; Arrays.fill(nums1,88); for(int i:nums1) System.out.print(i+" "); 输出 88 88 88 88 88 5.Arrays.copyOf(数组名,数组长度) 将数组进行复制,复制长度由你决定.当复制长度小于原来数组长度,则取数组的前面几个元素。若复制长度大于数组长度,则超过部分是类型数据的默认值 int[] nums2={21,22,23,24,25}; int[] copyNums2 = Arrays.copyOf(nums2,3); for(int i:nums2) System.out.print(i+" "); 输出21 22 23 6.Arrays.binarySearch(数组名,数据) 查询数组中某个数据的下标值,调用此方法之前应该先调用排序方法sort()方法,如果没有调用,不能保证结果的准确性。如果数组中不存在该元素,则会返回的是一个负数 int[] scores = {1, 20, 30, 40, 50}; //在数组scores中查找元素20 int res = Arrays.binarySearch(scores, 20); //打印返回结果 1 System.out.println("res = " + res);
-
二维数组的创建(方式一) 声名二维数组:数据类型[][] 数组名;或者 数据类型 数组名[][]; 分配空间:数组名 = new 数据类型[长度][长度]; 或者 数组名 = new 数据类型[长度][]; 赋值:数组名[下标][下标] = 数据; 例子: int[][] nums; nums = new int[3][2]; 这是分配了一个3行2列的二维数组 nums[0][0] =10; nums[0][1] =20; nums[1][0] =100; nums[1][1] =200; nums[2][0] =110; nums[2][1] =120; for(int i =0;i{数据1,数据2,...,数据n},{数据1,数据2,...,数据n},...,{数据1,数据2,...,数据n}}; 或 数据类型 数组名[][] = new 数据类型[][]{{数据1,数据2,...,数据n},{数据1,数据2,...,数据n},...,{数据1,数据2,...,数据n}}; String[][] strs = new String[][]{{"hello"},{"java","c++"},{"html","css","js"}}; 上述声明数组、分配空间、赋值可以简写成: 数据类型[][] 数组名 = {{数据1,数据2,...,数据n},{数据1,数据2,...,数据n},...,{数据1,数据2,...,数据n}}; 或 数据类型 数组名[][] = {{数据1,数据2,...,数据n},{数据1,数据2,...,数据n},...,{数据1,数据2,...,数据n}}; char[][] chars = {{'a','b'},{'c','d','e'},{'f'},{'g','k'}}; 注意: 方式二不要声名数组的长度 二维数组,第一个数代表的是行,第二个数代表的是列。 例如: int[][] arr =new int[3][4] 它表示的是3行4列的数。同int[][] arr={{1,2,3,4},{5,6,7,8},{9,10,11,12}} 这个表示的也是3行4列,这个{1,2,3,4}表示的是1行4列
public class Test8 {
public static void main(String[] args) {
Scanner sc =new Scanner(System.in);
System.out.println("请输入有多少个整数");
int n =sc.nextInt();
int[] arr =new int[n];
System.out.println("请输入这些整数");
for(int i=0;i
arr[i] = sc.nextInt();
}
System.out.println("排序前");
for (int i : arr) {
System.out.print(i+" ");
}
System.out.println("请输入向后移多少个位置");
int m =sc.nextInt();
int[] ar =new int[m];
//把最后面要移动的m个数赋给另外一个数组
int m1 =0;
for(int i= arr.length-m ;i
ar[m1]= arr[i] ;
m1++;
}
//把前面arr.length-m个数向后移动m个位置
int count =0;
for(int i=arr.length-m-1;i>=0;i--){
arr[arr.length-1-count] = arr[i];
count++;
}
//把最前面空出来的m个位置,从另外一个数组中获得数组中最后m个数
for(int i=0;i
arr[i] = ar[i];
}
System.out.println("排序后");
for (int i : arr) {
System.out.print(i+" ");
}
}
}
2.键盘上输入 3*4 的整型数组,求出最大值和最小值
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner sc =new Scanner(System.in);
int[][] arr =new int[3][4];
System.out.println("请输入12个数");
//for循环获取键盘上的12个数字
for(int i=0;i
arr[i][j] = sc.nextInt();
}
int min = arr[0][0];
int max = arr[0][0];
//双层for循环进行遍历,一一和max、min比较
for(int i=0;i
for(int j=0;j
if(arr[i][j]>max){
max =arr[i][j];
}
else if(arr[i][j]
min =arr[i][j];
}
}
}
System.out.println("最大值是:"+max);
System.out.println("最小值是:"+min);
}
}
3.键盘上输入 3*4 的整型数组,将四周的数据清0
import java.util.Scanner;
public class Test6 {
public static void main(String[] args) {
Scanner sc =new Scanner(System.in);
int[][] arr =new int[3][4];
System.out.println("输入12个数");
//从键盘上获取12个数
for(int i=0;i
for(int j=0;j
arr[i][j] = sc.nextInt();
}
}
//通过观察这个长方形,得出四周为0的规律
for(int i=0;i
for(int j=0;j
if(i==0||j==0||i==2||j==3)
arr[i][j] =0;
}
}
//二维数组遍历输出
for(int i=0;i
for(int j=0;j
System.out.print(arr[i][j]+" ");
}
System.out.println();
}
}
}
第四章 面向对象
1.类和对象的定义
-
类:具有相同属性和方法的多个对象的集合 对象:客观存在的一个实体(你能看得见摸得着的物体都可以看成是对象),具有属性和方法 属性:描述的是对象的特征 方法:描述的是对象的功能 综述: 类(学生类)是对象(张三这个具体的学生)的抽象,对象是类的具体,万事万物皆对象(桌子是类,当前这个桌子是对象,空调是类,当前这个空调是对象.....)
-
属性的定义语法: 声明属性:数据类型:属性名; 或 数据类型 属性名 = 数据 String type; String color = "白色"; 方法的定义语法: 访问权限修饰符 返回值类型 方法名(数据类型 变量名1,数据类型 变量名2,....数据类型 变量名n,){ //描述方法实现功能的代码 } 访问权限修饰符: public(公共的) protected(受保护的) private(私有的) 默认值(什么都不写) 返回值类型: 方法可以返回给你的结果类型,可以是8大基本类型,也可以是引用数据类型 如果没有返回值,那么写void ()里的称之为参数列表,参数可以没有,也可以有一个或者多个,多个之间使用,隔开,参数的数据类型可以是基本数据类型,也可以是引用类型 {}里的方法实现功能的具体代码 方法的调用规则: 在调用方法的时候,方法有返回值给你,返回给你什么类型的结果,你就要使用对应类型的变量去接受这个返回的结果 在调用有参方法的时候,方法需要什么参数,你就需要传递什么参数,要遵循方法参数列表的定义顺序来传递参数 注意: 对于输出语句:System.out.println();其中println()这个,它也是一个封装的方法,它可以接受 它可以不接受参数,就直接写 System.out.println(); 它也可以接受8大基本数据类型和引用数据类型(使用Object类型进行接受,它是所有类的父类.无论是自己创建的,还是JDk中的类都默认继承Object类), 但它不可以接受一个void类型的返回值,因为它没有定义一个void类型的返回值,也不可能有一个void x;这种类型 public void println(void x) {} 例如:错误示例 public void bark(){ System.out.println("汪汪汪"); } System.out.println(dog1.bark()); 方法的分类: 按照方法是否有返回值,可以将方法分为 有返回值的方法: 有返回值的方法需要使用到return关键字将结果返回 无返回值的方法: 写void表示方法没有返回值 按照方法是否有参数,可以将方法分为: 有参数的方法。简称有参方法 没有参数的方法。简称无参方法 综上所述: 没有返回值的无参方法 没有返回值的有参方法 有返回值的无参方法 有返回值的有参方法
-
对遍历和冒泡算法进行封装 public class ArrayMethod { //定义一个方法实现数组遍历 public void printArray(int[] array){ for (int i : array) { System.out.print(i+" "); } } //定义一个方法实现数组排序 public void sort(int[] array){ for (int i = 0; i < array.length-1; i++) { for (int j = 0; j < array.length-1-i; j++) { if(array[j]>array[j+1]){ int temp = array[j]; array[j]= array[j+1]; array[j+1] = temp; } } } } } 传参进行数组的排序和遍历 public class ArrayMethodTest { public static void main(String[] args) { int[] nums = {11,45,27,89,66,52}; ArrayMethod arrayMethod = new ArrayMethod(); System.out.println("数组排序前:"); arrayMethod.printArray(nums); System.out.println(); System.out.println("数组排序后:"); arrayMethod.sort(nums); arrayMethod.printArray(nums); } } 注意: 不能直接调用其它类中的方法,只能通过对象名.方法名()调用,或者通过类名.方法名()。只有在同一个类中,调用本类的方法,可以直接写方法名。但不能在静态方法中调用非静态方法 方式一 成立 public void bark(){ eat(); System.out.println("汪汪汪"); } public String eat(){ return "狗宝宝好饿"; } 方式二 成立 public void bark(){ eat(); System.out.println("汪汪汪"); } public static String eat(){ return "狗宝宝好饿"; } 方式三 直接编译错误 public static void bark(){ eat(); System.out.println("汪汪汪"); } public String eat(){ return "狗宝宝好饿"; }
-
在同一个类中,多个方法的方法名相同,参数列表不同,这个现象就是方法重载,与方法的返回值和访问权限无关,只关注两点方法名和参数列表 参数列表不同体现在参数的个数,参数的类型,参数的顺序 注意; 构造方法和普通方法都可以进行重载
-
每创建一个类,系统会自动给这个类添加一个无参构造方法,并且是隐藏的 (1)构造方法是用来创建对象的 (2)构造方法的名称与类相同 (3)构造方法没有返回值,void也不写 (4)当你在类中自定义了其它有参构造方法后,默认的无参构造方法会被覆盖,所以如果new的一个对象没有参数,需要我们自己添加一个无参构造方法 (5) 谁调用构造方法,this就指向哪个对象 super()调用父类的无参构造方法 -
例子 定义一个方法实现将Dog类数组里的dog对象按照年龄进行升序排序 public class Dog { public String name; public int age; } public class DogMethod { public void sort(Dog[] dog){ //由于Arrays.sort()方法是排列数组中的数字的,而这传过来的则是数组地址,所以需要额外定义一个数组 int[] arr = new int[dog.length]; for (int i = 0; i < dog.length; i++) { arr[i] = dog[i].age; } for (int i = 0; i < arr.length; i++) { Arrays.sort(arr); } for (int j = 0; j < arr.length; j++) { dog[j].age =arr[j]; } } } public class DogMethodTest { public static void main(String[] args) { Dog dog1 = new Dog(); dog1.age = 2; Dog dog2 = new Dog(); dog2.age = 6; Dog dog3 = new Dog(); dog3.age = 1; Dog dog4 = new Dog(); dog4.age = 3; Dog[] d ={dog1,dog2,dog3,dog4}; System.out.println("排序前年龄"); for (int i = 0; i < d.length; i++) { System.out.print(d[i].age+" "); } DogMethod dm =new DogMethod(); dm.sort(d); System.out.println("排序后年龄"); for (int i = 0; i < d.length; i++) { System.out.print(d[i].age+" "); } } }
-
成员变量 定义在类中方法外(循环结构外)的变量 作用域是整个类中 可以不进行初始化,系统会给一个默认值 同一个类中可以有同名的全局变量和局部变量,但使用原则遵循就近原则 局部变量 定义在方法内(循环结构内)的变量 作用域仅限于定于它的结构内 在使用之前要进行初始化,否则程序会报错 同一个方法中不能有同名的局部变量
-
将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过类提供的方法来实现对隐藏信息的操作和访问 把尽可能多的东西藏起来,对外提供便捷的接口 如何实现封装 1.修改属性的可见性 设为private,防止错误的修改(在另外一个类中不能直接对 对象的属性做操作) 2.创建共有的getter/setter方法 用于属性的读写 3.在getter/setter方法中加入属性控制语句 对属性的合法性进行判断 -
封装例子 public class Penguin { private String name; //如果前面不写修饰符,则就是默认的修饰符 private int health; private int love; public Penguin(String name, int health, int love) { super(); this.name = name; this.health = health; this.love = love; } public Penguin() { super(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getHealth() { return health; } public void setHealth(int health) { if(health<0){ System.out.println("你的宠物早就挂了,重新复活,默认负值60"); this.health =60; return; //return在方法中的作用有两个,一个是返回结果值,另一个作用是结束方法后续代码的执行 } this.health = health; } public int getLove() { return love; } public void setLove(int love) { if(love<0){ System.out.println("多和你的宠物培养感情,默认提升亲密度到70"); this.love =70; return; } this.love = love; } } public class PenguinTest { public static void main(String[] args) { Penguin p1 =new Penguin(); p1.setName("QQ"); p1.setHealth(-10); p1.setLove(-10); } } 解说 企鹅的健康度不可能是负值,如果对这个健康属性直接进行赋值,极度不合理。所以封装的好处就体现了(不是直接调用属性,而是直接调用方法) 类名只能被public和default修饰。不能使用其它的修饰符进行修饰
-
作用 1.允许类组成较小的单元(类似文件夹),易于找到和使用相应的文件 2.防止命名冲突,区分名字相同的类 3.有助于实施访问权限控制 -
如何创建包 用package声名包,以分号结尾,位置是在源代码的第一条语句(注释不算)
-
包命名规范 1.包名由小写字母组成,不能以圆点开头或结尾 package mypackage; 2.包名之前最好加上唯一的前缀,通常使用组织倒置的网络域名 package net.javagroup.mypackage; 3.包名后续部分依不同机构内部的规范不同而不同 package net.javagroup.research.powerpoint; (通常是部门名.项目名)
-
JDK提供基本包 java.lang:虚拟机自动引入 例如: 输出语句中的System,它是java.lang包下的System类,只不过不要我们手动导入了,虚拟机已经自动引入了 java.util:提供一些实用类 java.io:输入、输出 如何导入包 为了使用不在同一包中的类,需要在Java程序中使用import关键字导入这个类 import 包名. 类名;. import java.util.*; (导入java.util包中所有类 。 ) * 指包中的所有类,只是指util包下的所有类,不包括util包下的其它包 import cn.jtest.classandobject.School; //导入自己创建的包中指定类
-
1.一个类同时引用了两个来自不同包的同名类,必须通过完整类名来区分 例如 我们需要在同一个类中使用util和sql包下的Date类,则不能使用import的方式进行导入 import java.util.Date; import java.sql.Date; 需要使用完整类名来导入 java.util.Date date = new java.util.Date(); java.sql.Date date2 = new java.sql.Date(123456789L); 2.每个包都是独立的,顶层包不会包含子包的类 例如 java.util包 不包含java.util.logging包下的类 3.package和import的顺序是固定的 1)package必须位于第一行(忽略注释行) 2)只允许有一个package语句 3)第二个顺序是其次是import 4)第三个顺序是类的声明
-
类只能被public或者默认修饰符进行修饰 public修饰符 共有访问级别。 可以被任何地方的类进行访问 默认修饰符 包级私有访问级别。 只可以在同一个包中的其它类进行访问。别的包不行
-
private 只在同一个类中能够被访问 默认修饰符 在同一个类中和同一个包中可以被访问 protected 在同一个类中和同一个包中和子类中(子类和父类无论在不在同一个包中)可以被访问 public 任何地方都可以被访问
-
局部变量: 定义在方法内或者其它结构内的变量 成员变量: 定义在类中(其它结构(for、while、switch等)和方法)之外的变量
-
1.继承public和protected修饰的属性和方法,不管子类和父类是否在同一个包中 2.继承默认权限修饰符修饰的属性和方法,但子类和父类必须在同一个包中
-
private属性和方法 子类与父类不在同包,使用默认访问权限的成员 构造方法
-
符合is-a关系的设计使用继承 例如 藏獒是一种狗 狗是一个类,藏獒是狗的具体实例化。边牧也是狗的实例化,所以这两个品种的狗都有狗的特征,所以狗可以是个父类 猫是哺乳动物 猪也是哺乳动物、大象也是哺乳动物。所以可以提取他们的共同点,作为哺乳动物的属性 继承是代码重用的一种方式,将子类共有的属性和行为放到父类中
-
子类访问父类成员 访问父类构造方法 super(); (此语句只能在构造方法中出现) super(参数); (此语句只能在构造方法中出现) 访问父类属性 super.属性名 (出现在子类中的任何地方) 访问父类方法 super.方法名 注意: 1.子类不能够访问父类中定义为private的属性和方法 2.在子类构造方法中,即使不写super(),它也是存在的。如果自己要写的话,必须放在构造方法中的第一行 当在子类构造方法中写了super(有参),则super()会消失. 即他们都必须都要在第一行,所以在同一个子类构造方法中,只能写一个或者不写默认是super(),super()或者super(有参) 3.super只能出现在子类的方法和构造方法中 4.super不能访问父类private成员(方法和变量) 5.在子类中,调用父类构造函数,只能在子类构造函数中调用。 例子(容易忘记隐形的super()) class Car { private int site = 4; //座位数 Car(){ System.out.println ("载客量是"+site+"人"); } public void setSite(int site){ this.site = site; } void print(){ System.out.print("载客量是"+site+"人"); } } class Bus extends Car { Bus(int site){ setSite(site); } } public static void main(String[] args) { Bus bus = new Bus(20); bus.print(); } 输出结果是 载客量是4人 载客量是20人
-
1.能被类的所有实例共享,可作为实例之间进行交流的共享数据 2.如果类的所有实例都包含一个相同的常量属性,可把这个属性定义为静态常量类型,从而节省内存空间
-
类变量(静态变量) 被static修饰的变量 在内存中只有一个拷贝 类内部,可在任何方法内直接访问静态变量 其他类中,可以直接通过类名访问
静态方法内,可以调用非静态方法(非静态变量)和静态方法(静态变量),而在非静态方法内不可以调用静态方法(有问题)
实例变量
没有被static修饰的变量
每创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个拷贝,互不影响
注意:
局部变量不能加static,包括protected,private,public都不能加
全局变量都可以加
因为:
静态变量和常量是在编译时确定的,而方法的局部变量是在运行时确定的,也就是说方法是可以变的,在方法体不在在被对象所使用的时候,方法体也就被回收了,
可是如果方法中有静态方法就不可以了,因为静态变量是不可以被回收的,他会随着类的存在而一直存在,所以这是矛盾的,所以方法中不可以有静态变量
在实例方法里不可以定义static变量
public void f(){
static int x =0; //这是错误的
}
在静态方法里也不可以定义static变量
public static void f(){
static int x =0; //这是错误的
}
11.重写和多态
11.1 重写
-
什么是方法重写? 子类根据需求对从父类继承的方式进行重新编写 重写时,可以用super.方法的方式来保留父类的方法 构造方法不能被重写
-
方法重写规则 方法名相同 参数列表相同 返回值类相同 子类访问权限不能高于父类 父类的静态方法不能被子类覆盖为非静态方法,父类的非静态方法不能被子类覆盖为静态方法 父类的私有方法不能被子类覆盖 不能抛出比父类方法更多的异常
-
重写与重载的比较 方法重写: 子类中的方法名、参数列表、返回值都要相同。访问修饰符不能比父类严格 方法重载:是在同一个类中,方法名相同,参数列表不相同,与返回值和访问修饰符无关
-
toString() Object中的toString()方法,返回当前对象本身的有关信息 例如 Student student =new Student("张三",20); System.out.println(student.toString()); 输出内容:com.bdqn.demo03.Student@2e739136 toString()方法实现 public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); } 扩展 System.out.println(对象名); PrintStream.class public void println(Object x) { String s = String.valueOf(x); synchronized (this) { print(s); newLine(); } } String.class public static String valueOf(Object obj) { return (obj == null) ? "null" : obj.toString(); } 解释上段代码作用 第一步 调用println(对象名) 第二步 把对象名传参给String类的valuOf()方法 第三步 根据valueOf()方法里进行判断,若对象是null,则返回null,否则对象会调用toString()方法 (子类继承父类,如果子类调用的方法重写父类了,则调用自己重写的,否则调用父类的) -
equals() Object中的equals()方法,返回的是两个对象地址值的比较或者两个数值的比较 例如 Student student =new Student("张三",20); Student student1 =new Student("张三",20); System.out.println(student1.equals(student)); 输出内容:false equals()方法实现 public boolean equals(Object obj) { return (this == obj); //this指的是当前对象,即谁调用equasl()方法谁就是this } == 比较引用是比较地址值是否相同 (引用类型包括 数组,类和接口) 比较数值是比较数值是否相同 注: Object类的equals()方法与==没区别 当有特殊需求,如认为属性相同即为同一对象时,需要重写equals() Java.lang.String重写了equals()方法,把equals()方法的判断变为了判断其值
-
public class Student { private String name; private int age; //父类Objec类中的toString()不能满足Student类的使用,那么就重写Object类中的toString()方法 @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } //重写Object类中的equals()方法:如果两个对象的name和age值一样,就认为两个对象是同一个对象 @Override public boolean equals(Student stu) { //自己跟自己进行比较 if(this==stu){ return true; } //两个对象进行比较,比较姓名和年龄,姓名是String类型,比较内容,采用String里的equals()方法,比较年龄,采用==比较 if(this.name.equals(stu.name)&&this.age==stu.age){ return true; } return false; } } public class Demo01 { public static void main(String[] args) { //创建两个学生对象 Student stu1 = new Student("张三", 22); Student stu2 = new Student("张三", 22); boolean result2 =stu1.equals(stu2); System.out.println(result2); //true 若不重写则输出false System.out.println(stu1.toString()) //Student [name=张三, age=22] 若不重写输出的是 com.bdqn.demo03.Student@2e739136 即 包名.类名@... } }
-
什么是多态 同一个引用类型,使用不同的实例(对象)而执行不同操作(Animal animal 然后子类传参,可以传new Dog()对象等) 例子 (动物类) public class Animal { private String name; private int health; private int love; public Animal() { super(); } public Animal(String name, int health, int love) { super(); this.name = name; this.health = health; this.love = love; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getHealth() { return health; } public void setHealth(int health) { this.health = health; } public int getLove() { return love; } public void setLove(int love) { this.love = love; } // 定义一个输出动物信息的方法 public void print() { System.out.println("动物昵称:" + this.name + ",健康值:" + this.health + ",亲密度:" + this.love); } //定义一个Animal去医院看病的方法 public void toHospital(){ System.out.println("去医院找医生看病....."); } } (猫类) public class Cat extends Animal{ private String color; public Cat(String name, int health, int love, String color) { super(name, health, love); this.color = color; } public Cat() { super(); } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public void print(){ super.print();System.out.println("宠物颜色:"+color); } public void toHospital(){ System.out.println("(猫)打针......"); this.setHealth(90); } } (狗类) public class Dog extends Animal { private String strain; public Dog(String name, int health, int love, String strain) { super(name, health, love); this.strain = strain; } public Dog() { super(); } public String getStrain() { return strain; } public void setStrain(String strain) { this.strain = strain; } public void print(){ super.print(); System.out.println("宠物品种"+strain); } public void toHospital(){ System.out.println("(狗)吃药......"); this.setHealth(88); } } (主人类) public class Master { //带宠物去看病 public void cure(Animal animal){ //打印宠物基本信息 animal.print(); //宠物健康值小于60,看病 if(animal.getHealth()<60){ System.out.println(animal.getName()+"的健康值小于60"); animal.toHospital(); } } } (测试类) public class Test { public static void main(String[] args) { Master master = new Master(); Animal dog =new Dog("翠花",59,90,"拉布拉多"); master.cure(dog); System.out.println("****************"); Animal cat =new Cat("大咪咪",49,95,"大白"); master.cure(cat); } } 解释说明: 狗和猫都需要去医院看病,但他们看病的方式不同,即方法相同,但方法内部不同,所以可以在他们父类中定义一个toHospital()方法,然后让狗类和猫类去重写这个方法,然后最最最重要的就是主人类了,它使用了父类作为基本类型,所以直接在测试类中传对象就可以了 注意1: 方法重写是多态的基础。没有重写就没有多态。 在这个例子中,如果没有Animal类中的toHospital()方法,而直接用多态会报错,因为你Animal中都没有toHospital()方法,你用animal.toHospital()编译一定通不过的 注意2: 在这个例子中,Animal类中的toHospital()方法,其实是没有用的,但又不能不写,所以可以定义成一个抽象方法
-
抽象方法可以在抽象类中定义,也可以在接口中定义。普通类不行 抽象方法没有方法体 public abstract class Patients{ public abstract void tackMedicine(); } 在抽象类中可以定义普通方法,也可以有抽象方法,也可以没有抽象方法 抽象方法所在的类要声明为抽象类 子类继承抽象父类,必须要重写父类中的所有抽象方法,如果不重写,子类也要定义成抽象类 抽象类不能实例化,实例化没有任何意义 对11.4的例子进行修改(变成抽象类,toHospital()变成抽象方法) (动物类) public abstract class Animal { private String name; private int health; private int love; public Animal() { super(); } public Animal(String name, int health, int love) { super(); this.name = name; this.health = health; this.love = love; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getHealth() { return health; } public void setHealth(int health) { this.health = health; } public int getLove() { return love; } public void setLove(int love) { this.love = love; } // 定义一个输出动物信息的方法 public void print() { System.out.println("动物昵称:" + this.name + ",健康值:" + this.health + ",亲密度:" + this.love); } //定义一个Animal去医院看病的方法 public abstract void toHospital(); }



