admin管理员组

文章数量:1664854

环境的准备:
第一步:下载并安装JDK8
第二步:配置环境变量:配置哪个JDK,哪个就生效
1)JAVA_HOME 配置的是JDK的根目录C:\Program Files\Java\jdk1.8.0_241
2)Path: 不需要新建,配置的是JDK的bin目录
3)CLASSPATH ,需要新建,配置的是JDK的lib目录
验证:只要win+R输入命令:java -version 出现版本信息就说明配置正确
1 Java的标识符
由字母 数字 下划线 美元符号 组成
不能以数字开头
严格区分大小写
见名知意,并且不要使用拼音或者中英文夹杂的方式
不能使用关键字
2 关键字
被Java提前指定好的全小写单词,一共有50个
2个保留字:const 与 goto ,目前还没有明确意义的关键字
还有3个不可以用作标识符的单词:true false null
3 注释
用来解释代码,方便看看代码的人去理解代码的话

注释并不会影响程序的执行,会被编译器忽略掉
单行注释: // 可以注释一行的内容
多行注释:/ * * / 可以注释多行的内容
文档注释:/** */ 也可以注释多行内容,还可以添加一些额外的信息,比如:作者/时间/版本…
4 数据类型
4.1 基本类型

八大基本类型
byte:8位,最大存储数据量是255,存放的数据范围是-128~127之间。

short:16位,最大数据存储量是65536,数据范围是-32768~32767之间。

int:32位,最大数据存储容量是2的32次方减1,数据范围是负的2的31次方到正的2的31次方减1。

long:64位,最大数据存储容量是2的64次方减1,数据范围为负的2的63次方到正的2的63次方减1。

float:32位,数据范围在3.4e-45~1.4e38,直接赋值时必须在数字后加上f或F。

double:64位,数据范围在4.9e-324~1.8e308,赋值时可以加d或D也可以不加。

boolean:只有true和false两个取值。

char:16位,存储Unicode码,用单引号赋值。

4.2 引用类型
我们学习的是String字符串类型,这个类型的数据需要使用双引号包裹

5 案例中总结的经验:
静态数据字符串想要与动态的变量名进行拼接,需要使用+号
char字符型既可以保存单个字符,需要用‘ ’包裹,也可以保存数字,只不过数字会去查ASCII码表
从控制台接受用户输入的数据:int a = new Scanner(System.in).nextInt();
变量进行值交换,首先需要一个第三方变量协助交换,代码的格式:斜相对,首尾相连
6 变量定义
定义的时候并且赋值:变量的类型 变量名 = 变量值; 比如:int a = 19;
先定义,后面再赋值:int a; a=99;
注意:=是赋值符号,等号右边的值交给等号左边的变量来保存
7 类型转换
boolean类型不参与类型转换
小转大,直接转 – 隐式转换
大转小,强制转 – 显式转换,格式:byte b = (byte) a;
浮变整,小数没 – 浮点型转整形是直接舍弃所有的小数部分的,不会四舍五入
类型能否转换,取决于类型的取值范围,而不是字节数,字节数只能做大概的参考
8 5条字面值规则
整数默认为int类型
小数默认为double类型
byte short char 三种比int小的类型,可以使用范围内的值直接赋值
字面值后缀:L F D
字面值前缀:0b-2 0-8 0x-16
9 5条运算规则
运算结果的数据类型与最大类型保持一致
3种比int小的类型,运算时会自动提升成int再运算
整数运算溢出的问题,一旦溢出,数据就错误了
浮点数运算不精确
浮点数的特殊值 Infinity NaN

1 运算符
普通的四则运算 + - * / 是不会改变变量本身的值的
如果想要改变变量本身的值,需要把表达式的结果重新赋值给变量
取余%(求模 mod) : 取余数,如果整除,余数为0
自增自减运算符
自增++ :表示变量本身的值+1
自减- - : 表示变量本身的值-1
前缀式:符号在前,先改变变量本身的值,再使用,比如打印,计算…
后缀式:符号在后,先使用,再改变变量本身的值
比较运算符
!= == > < >= <= 比较的结果都是布尔类型的
逻辑运算符
&&:双与/短路与:逻辑与单与相同,全真才真,只不过增加了短路的效果
||:双或/短路或:逻辑与单或相同,全假才假,只不过增加了短路的效果
三目/三元运算符
格式:1 ?2 :3;1是表达式,若1真,取2,若1假取3
赋值运算符
= :是普通的赋值运算符,等号右边的值交给等号左边的变量来保存
复合赋值运算符:+= -= *= /=,主要是可以简写&类型的自动转换
sum += 30; 等效于 sum = sum+30;
2 流程控制
2.1 顺序结构
顺序结构从头到尾所有代码依次都会执行到
可以解决输入 输出 计算等问题,但是不可以先做判断,再选择性的执行代码

2.2 分支结构
1 单分支结构
适合只有一个判断条件时使用,符合条件,执行大括号里的代码,不符合条件,大括号里的代码跳过

2 多分支结构
适合有两种情况时使用,符合条件,执行代码1,其他情况执行代码2

3 嵌套分支结构
适合有多个条件时使用,else-if的个数没有限制,else可加可不加

if(判断条件1) {
    如果符合判断条件1,执行此处代码1,如果不符合,继续向下判断条件2
}else if(判断条件2) {
    如果符合判断条件2,执行此处代码2,如果不符合,继续向下判断条件3
}else if(判断条件3) {
    如果符合判断条件3,执行此处代码3,如果不符合,继续向下判断
}else {
    如果以上条件都不满足,执行此处代码
}
4 选择结构
switch(a){
       case 1 : 操作1;break;【可选】
       case 2 : 操作2;break;【可选】
       case 3 : 操作3;break;【可选】
       case 4 : 操作4;break;【可选】
       default : 保底选项;【可选】
}

执行顺序:先拿着变量a的值,依次与每个case后的值做比较,如果相等,就执行当前case后的操作,若case后没有break,就绪继续执行下一个case后的操作,如果一直没有遇到break,就会发生穿透的现象,包括default

注意事项:

变量a支持的类型byte short char int String
变量a的数据类型与case后value的数据类型必须一致
如果没有添加break,并且又有case被匹配到,会发生穿透的现象,包括deafult
case的个数 是否加break 是否加default 完全根据自己的业务来决定
如果添加了default保底选项,又没有任何一个case被匹配到,就会执行default后的语句
一般我们习惯在每个case后加break【这个只是建议,具体还是根据业务来写】
5 循环结构
当你想多次重复干某件事的时候,可以使用循环结构
注意事项:开始条件只会在第一轮执行一次,剩下两个条件才会执行多次

普通for循环

for(开始条件 ; 循环条件 ; 更改条件){
     循环体
}
注意1:写法小窍门:从哪开始 到哪结束 循环变量如何变化
注意2:for循环能够执行多少次,取决于循环变量可以取到几个值

1 for循环
格式:
public static void main(String[] args) {
        for(开始条件; 循环条件 ; 更改条件) {
            符合循环条件后执行的循环体
        }
}
循环的开始条件只会在第一轮开始的时候执行一次,后续均不再执行
循环结构适合我们在程序中需要反复执行某一件事时使用
循环能够执行几次,取决于循环变量能够取到几个值,而不是循环变量的取值范围

public static void main(String[] args) {
        //比如此处循变量i的取值范围是8~8888,但是循环只执行了4次
        //因为i只取到了4个值,分别是8,88,888,8888
        for (int i = 8; i <= 8888; i=i*10+8) {
            System.out.println(i);
        }
    }
我们可以通过break直接结束当前循环的剩余所有轮
我们可以通过continue结束本轮循环continue后面的语句,直接开始下一轮循环
我们可以使用return关键字结束整个方法,注意break continue return 后都不可以直接写代码,都是不可到达的代码
2 嵌套for循环
外层循环控制的是执行的轮数,内层循环控制的是这一轮中执行的次数
外层循环控制的是图形的行数,内层循环控制的是这一行的列数
案例中的经验:
如果把内层循环循环变量的最大值设置为一个固定值,打印出来的是矩形

//*****
//*****
//*****
        for(int i = 1; i<=3 ;i++) {//外层循环,控制的轮数,执行3轮
            for(int j = 1;j<=5;j++) {//内层循环,控制的是每轮的次数,每轮执行5次
                System.out.print("*");
            }
            System.out.println();//本打印语句用来换行
        }

如果把内层循环的循环变量j,设置成随着外层循环循环变量i的变化而变化,打印出来的是直角三角形

System.out.println("*********打印左直角三角形********");
for(int i = 1;i<=6;i++) {//外层循环控制的是行数
    /**矩形每行中*的个数是固定不变的
     * 而左直角三角形中每行星星个数的最大值是随着行数的变化而变化的,行i星i*/
    for(int j = 1; j<=i;j++) {//内层循环控制的是这一行的列数
        System.out.print("*");
    }
    System.out.println();//打印空白行用来换行,注意一定要内层循环结束
}    

3 while循环
先判断,再执行,注意while循环设置死循环后必须设置出口~

while(判断条件){ 
    循环体
}
4. do-while循环
先执行,再判断,本循环最少会执行一次

do{
        循环体
}while(判断条件);
5 几种循环的区别
for:知道循环次数
while/do while:当循环次数不确定时
while:先判断,不符合规则,不执行代码
do while:代码最少被执行一次,再去判断,符合规则,再次执行代码
循环之间都可以互相替代,但是一般最好选择合适的循环结构来完成代码哦~

6 成员变量与局部变量
成员变量:
1)位置:类里方法外
2)注意事项:成员变量有自己的对应类型的默认值,不需要我们手动初始化/赋值
3)生效范围:在整个类中都生效,类消失,成员变量才会随之释放
局部变量:
1)位置:在方法里 / 局部代码块里
2)注意事项:使用时必须赋值/初始化
3)生效范围:在方法里/局部代码块中,对应的代码执行完毕,局部变量也随之释放


7 方法
方法定义的格式: 修饰符 返回值类型 方法名(参数列表){方法体}
一个方法会不会执行,取决于有没有调用,调用的格式:方法名+参数列表
方法定义的位置没有关系,执行顺序取决于main()怎么调用
一个方法,可以不设置参数,也可以设置多个参数,如果有参数,使用方法时,必须传对应类型的参数
如果方法的返回值类型是void,不允许有返回值
如果方法要返回一个值,必须设置返回值类型,并且return对应类型的结果
在调用有返回值的方法时,可以接这个方法的返回值,接到了后续可以多次使用这个返回值
如果不接,那就是只是调用该方法的功能,并不使用这个返回值

public class TestMethod2 {
    public static void main(String[] args) {
        //我们通过方法名+参数列表来确定调用哪个方法
        run();
        eat(5);
        String r = play("二郎神");
        System.out.println("我是r:"+r);
    }
    //格式:修饰符 返回值类型 方法名(参数列表){方法体}
    //需求1:定义一个方法run,没有参数,没有返回值,打印:小狗DOG跑的老快了~
    public static void run() {
        System.out.println("小狗DOG跑的老快了~");
    }
    //需求2:定义一个方法eat,参数为int n,没有返回值,打印:小狗今晚要吃n个肉包子~
    private static void eat(int n) {
        System.out.println("小狗今晚要吃"+n+"个肉包子~");
    }
    //需求3:定义一个方法play,参数String host,返回值是String "飞盘"
    //打印:小狗Dog与主人host玩的很开心~
    public static String play(String host) {
        System.out.println("小狗Dog与主人"+host+"玩的很开心~");
        return "飞盘";
    }
}

运行结果
小狗DOG跑的老快了~
小狗今晚要吃5个肉包子~
小狗Dog与主人二郎神玩的很开心~
我是r:飞盘

数组
1.1 静态创建
int[] a = {1,2,3,4,5};
int[] a = new int[]{1,2,3,4,5};

1.2 动态创建
int[] a = new int[5];

1. 3 数组的创建过程
在内存中开辟连续的空间,用来存放数据
给数组完成初始化过程,给每个元素赋予默认值
数组完成初始化会分配一个唯一的地址值
把唯一的地址值交给引用类型的变量a去保存
如果想要操作数组中的元素,可以根据变量保存的地址找到数组,然后根据下标来操作数组的具体元素
数组名保存的是数组的地址值,不是数组中每一个具体的元素,数组名是一个引用类型的变量


2. 数组的特性
数组的长度通过**数组名.length;**来获取
数组一旦创建,长度无法改变
数组的下标从0开始,最大下标为数组长度-1
如果访问到了不存在的下标,会数组下标越界异常
3. 数组的工具类Arrays
toString(数组名),除了char类型以外,其他类型的数组想要查看数组的具体元素,都得使用这个方法,如果不用,打印是数组的地址值
sort(数组名),给数组进行排序
copyOf(要复制的数组,新数组的长度)
如果新的长度大于原数组的长度–数组的扩容
如果新的长度小于原数组的长度–数组的缩容
如果新的长度等于原数组的长度–普通的复制
注意:不管是什么长度,都不是修改原数组,而是创建新数组


4. 数组的遍历
如果只是想查看数组中有哪些元素,直接使用System.out.println(Arrays.toString(数组名));就可以
如果想要拿到数组中的一个个的具体元素,或者是对数组中的元素做进一步的操作,就需要对数组进行遍历
遍历:把数组中的所有元素,从头到尾逐个“过一遍”
通过循环遍历数组,所以循环中的循环变量代表的是数组的下标

public class ReviewDemo {
    public static void main(String[] args) {
        int[] a = new int[10];
        for(int i = 0;i<a.length;i++) {
            //System.out.println(i);//打印的是数组的下标0-9
            a[i] = i+11;//a[i]代表的是数组中每一个具体的元素
        }
        System.out.println(Arrays.toString(a));
        //[11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
    }
}

5. 方法的重载
我们根据方法名+参数列表确定具体调用哪个方法
方法的重载:在同一个类中,存在方法名相同,但参数列表不同的方法
如果在同类中,同名方法的参数个数不同,一定构成重载
如果在同类中,同名方法的参数个数相同,需要查看对应位置上参数的类型,而不是参数名,与参数名无关

比如:
(int a,String b)与(int b,String a)–不构成重载
(int a,String b)与(String a,int b)–构成重载

6. 冒泡排序
冒泡排序详细笔记
排序思路:要比较多轮,每轮两个相邻的元素做比较,位置不对就互换
代码思路:
通过嵌套for循环来完成

外层循环:控制的是轮数,如果有n个数,最多n-1轮
内层循环:控制的是每轮中比较的次数,每一轮的次数会递减,之前轮确定的最大值不应该参与后面轮的比较
注意:外层循环的循环变量代表的是轮数1 2 3 4…
内层循环的循环变量代表的是数组的下标[0,a.length-i)

7. 简易计算器实现
package cn.tedu.review;

import java.util.Scanner;

/*本类用于实现简易计算器*/
public class TestCalc {
    public static void main(String[] args) {
        f0();//调用一个实现计算器的方法
    }

    private static void f0() {
        while(true){//死循环,让用户可以一直算
            //1.提示并接收用户输入的两个数
            System.out.println("请您输入要计算的第1个数:");
            int a = new Scanner(System.in).nextInt();
            System.out.println("请您输入要计算的第2个数:");
            int b = new Scanner(System.in).nextInt();

            //2.提示并接收用户输入的运算符
            System.out.println("请您输入要计算的运算符,支持:+ - * / :");
            String s = new Scanner(System.in).nextLine();
            //3.根据运算符的不同,调用不同的计算方法进行计算并输出结果
            switch(s){
                case "+" : f1(a,b);break;
                case "-" : f2(a,b);break;
                case "*" : f3(a,b);break;
                case "/" : f4(a,b);break;
                default: System.out.println("您输入的运算符不正确!");
            }
            //4.询问用户是否想继续运算
            System.out.println("如果想退出,请输入1,继续请输入2");
            int flag = new Scanner(System.in).nextInt();
            if(flag == 1){break;}
        }
    }

    private static void f4(int a, int b) {//将拿到的两个数a和b做除法运算并打印结果
        System.out.println(a+"和"+b+"做除法的结果为:"+(a/b));
    }
    private static void f3(int a, int b) {//将拿到的两个数a和b做乘法运算并打印结果
        System.out.println(a+"和"+b+"做乘法的结果为:"+(a*b));
    }
    private static void f2(int a, int b) {//将拿到的两个数a和b做减法运算并打印结果
        System.out.println(a+"和"+b+"做减法的结果为:"+(a-b));
    }
    private static void f1(int a, int b) {//将拿到的两个数a和b做加法运算并打印结果
        System.out.println(a+"和"+b+"做加法的结果为:"+(a+b));
    }
}
1. 面向过程:
这种编程思想强调的是过程,凡事亲力亲为

2. 面向对象:
这种思想强调的是结果,Java就是一门面向对象的语言
不在意完成的过程,在意的是有对象可以帮我干活
比如:我们想吃饭,不在意是哪个厨师做的,也不在意是哪个骑手送的,只要有厨师做,有骑手派送就好了
我们可以把OOP的思维理解成一种行为习惯 思维方式
比如衣服,没有办法给出一个明确的定义,但是,只要我们看到任何一件衣服,我们就自动把它归类到衣服这个分类中,因为你在过去的生活经验中已经见过太多的衣服,积累经验

3.类
类指的是类型Type,是指一类事物,使用Java中的class关键字来描述
类是抽象的,要提取这一类事物的特征与功能
可以把类理解成设计图纸,模板
注意:类在现实世界中不是真实存在,它只是一种对象的数据类型

4.对象
对象就是根据类创建出来的一个个独立且具体的实例
一个类可以创建出多个对象,我们通过对象唯一的地址值区分不同的对象
对象具有各种特征,并且每个对象的每个特征都可以有自己特定的值
对象具有各种行为,每个对象可以执行的操作

5.对象创建过程分析
Phone p = new Phone();创建对象时,内存发生了什么?

在栈内存中开辟一块空间,Phone类型的引用类型变量p,把p压入栈底,此时p只有一个默认值null
在堆内存中开辟一块空间用于存放Phone类型的对象
要给这个对象进行初始化,比如:String brand = null;
此对象已经准备好,所以会生成一个唯一的地址值,并将这个地址值交给栈内存中的变量p来保存
如果后续想要对对象做操作,比如:p.price=88.8;先会找到栈中p变量保存的地址值,根据这个地址找到堆中的对象再做进一步的操作

3.面向对象的特征–封装
3.1为啥要用封装?
封装可以提高程序的安全性
封装可以让资源按照我们预先规定的方式来操作
3.2属性的封装
用private修饰属性,一旦属性被private修饰,就只能在本类中使用,外界无法访问
所以为了让外界能够按照我们提供的方式来调用,需要根据属性生成公共的getXxx()与setXxx()方法

3.2 方法的封装
方法的封装也是使用private来修饰方法
如果想要调用私有方法的功能,就需要在本类的公共方法里调用这个私有方法

1.构造函数:
格式:与本类类名同名,且没有返回值类型
作用:创建对象
执行时机:每次创建对象时都会执行构造方法
分类:
1)无参构造:默认存在,如果添加了其他构造,默认的构造函数会被覆盖,所以要记得手动提供哦~
2)含参构造:对于参数没有任何要求,有参数就行
3)全参构造:全参构造的参数必须与本类属性一致
全参构造不仅可以创建对象,还可以给对象的所有属性赋值

2.方法的重载
在同一个类中,存在多个方法名相同,但参数列表不同的方法
如果在同类中,多个同名方法的参数个数不同,一定构成重载
如果在同类中,多个同名方法的参数个数相同:需要查看对应位置上的参数的类型,而不是参数名,与参数名无关
如:(int a ,String b)与(int b,String a)–不构成重载
(int a,String b)与(String a,int b)–构成–构成重载


3.构造代码块:
位置:类里方法外
执行时机:每次创建对象时执行,并且优先于构造方法执行
作用:用于提取所有构造方法的共性功能
4.局部代码块:
位置:方法里
执行时机:调用本局部代码块所处的方法时执行
作用:用于控制变量的作用范围
执行顺序:
构造代码块->构造方法->普通方法->局部代码块

5.2 super的用法:
1.当父类的成员变量与子类的变量同名时,使用super指定父类的成员变量
2.使用super在子类构造方法的第一行调用父类构造方法的功能
super();–调用的是父类的无参构造
super(参数);–调用的是父类对应参数的构造方法

6. 继承
继承的关键字extends 格式: 子类 extends 父类
继承相当于子类把父类的功能复制了一份
Java只支持单继承:一个子类只能有一个父类,一个父类可以有多个子类
继承具有传递性:爷爷的功能会传给爸爸,爸爸的功能会传给孙子
子类只可以使用父类的非私有资源,私有资源由于private限制,不可用
子类可以拥有自己的特有功能
继承是is a 强耦合的关系,依赖性非常强,比如我们看到”熊孩子”,就知道他有一个”熊父母”

7 继承中的构造方法
子类在创建对象时,默认会先调用父类的构造方法
原因是子类构造函数中的第1行默认存在super();–表示调用父类的无参构造
当父类没有无参构造时,可以通过super(参数);调用父类的其他含参构造
注意:子类必须调用父类的一个构造函数,不论是无参还是含参,选一个即可
构造方法不可以被继承!因为语法的原因,要求构造方法的名字必须是本类类名
不能在子类中出现一个父类名字的构造方法

1.继承中变量的使用
父类成员变量与子类成员变量同名时,使用super.变量名指定父类的成员变量
2.继承中构造方法的使用
创建子类对象时,会先调用父类的无参构造,因为子类的构造函数中默认存在一个super();
如果父类没有无参构造的话,我们就需要手动指定子类去调用父类的含参构造super(参数);
构造方法不可以被继承,原因是:构造方法名必须是本类的类名,不可能在子类中存在一个父类名字的构造方法

3.方法的重写
重写:子类对父类的方法不满意时,可以重写父类的方法
注意:重写是在不改变父类方法的前提下,实现功能的修改,重写后子类对象调用的就是重写后的功能
原则:两同 两小 一大
两同:方法名+参数列表相同
一大:子类方法的修饰符权限 >= 父类方法的修饰符权限
两小:子类方法的返回值类型,有两种选择:
1)子类方法的返回值类型与父类方法的返回值类型相同
2)子类方法的返回值类型是父类方法的返回值类型的子类
比如:父:void 子:void
父:int 子:int 但是:byte short long都不行!没有继承关系
父:Animal 子:Animal/Cat都可以,但不可以是Car
注意:我们还可以给方法上加@Override注解,标记这是一个重写的方法

package cn.tedu.review;
/*本类用于回顾继承*/
public class TestExtends {
    public static void main(String[] args) {
        //7.创建子类对象进行测试
        ComputerStudent s1 = new ComputerStudent(1,"张三",'男',98);
        MathStudent s2 = new MathStudent(2,"李四",'女',89);
        ChineseStudent s3 = new ChineseStudent(3,"王五",'女',100);
        //8.利用创建好的对象进行方法测试
        s1.proClass();
        s1.hobby();
        s2.proClass();
        s2.hobby();
        s3.proClass();
        s3.hobby();
        //9.创建父类对象进行方法测试
        Student s0 = new Student(0,"海绵宝宝",'男',3);
        s0.thinkingClass();
        s0.proClass();
    }
}
//1.定义学生类
class Student{
    //2.定义学生的属性
    int sno;//学号
    String name;//姓名
    char gender;//性别
    double score;//分数

    //6.1添加父类的全参构造
    public Student(int sno, String name, char gender, double score) {
        this.sno = sno;
        this.name = name;
        this.gender = gender;
        this.score = score;
    }
    //3.1定义父类的功能
    public void thinkingClass(){
        System.out.println("正在上思修课");
    }
    //3.2定义父类的功能
    public void proClass(){
        System.out.println("正在上专业课");
    }
}
//2.定义学生类的子类,区分不同的专业
class ComputerStudent extends Student{//计算机专业学生
    //6.2生成子类的全参构造,并调用父类的全参构造
    public ComputerStudent(int sno, String name, char gender, double score) {
        super(sno, name, gender, score);
    }
    //4.1重写父类的功能
    @Override
    public void proClass(){
        System.out.println("正在上编程课");
    }
    //5.1定义子类的特有功能
    public void hobby(){
        System.out.println("喜欢敲代码~");
    }
}
class MathStudent extends Student{//数学专业学生
    //6.3生成子类的全参构造,并调用父类的全参构造
    public MathStudent(int sno, String name, char gender, double score) {
        super(sno, name, gender, score);
    }
    //4.2重写父类的功能
    @Override
    public void p

本文标签: 知识Java