文章

Java foundation

从0开始的Java学习之路。

一、入门

1、JVM

JVM:Java Virtual Machine Java 虚拟机

Java 虚拟机作用:字节码翻译成计算机可以读懂的代码

2、JVM与跨平台原理

image-20241020203747808

3、编写、编译、执行

①编写程序,后缀名为.java

②使用javac命令编译,后缀为.class

③使用通过java命令执行(直接输入文件名执行,不用写后缀)

4、架构

image-20240922220948846

image-20240923093809847

字节码文件:

字节码文件只有Java虚拟机可以读懂(.class)

5、JavaSE和JavaEE

Java 里面有一些核心技术。分成两大类: JavaSE(普通的桌面应用,控制台)和 JavaEE(开发网站)。

6、JDK和JRE

JDK(Java Developer Kit : Java 开发工具包)和JRE(Java Runtime Environment : Java 运行时环境),如果我们安装了 JDK,默认JRE也被安装了。

JDK 里面包含的内容要多于JRE。JRE只用提供运行环境就可以了,JDK 既要提供开发编译环境,也要提供运行环境。

### 7、快捷键

1
2
3
4
psvm
    public static void main(String[] args){}
sout
    System.out.println();

二、基础

1、变量概念

变量类型的不同,决定了在内存中占用空间大小的不同。

变量三要素:

1
2
3
4
5
类型: 决定了占用空间的大小

名称: 如何提取数据

变量值: 可以改变的。

2、命名规范:

1)标识符不能和系统里的关键字同名

2)标识符只能包括字母、数字和下划线”_”,并且开头只能是字母或下划线

3)标识符必须先定义、后使用

4)在同一作用域内,标识符不能重复定义

5)标识符是区分大小写的,如sum 和 Sum 是不同的标识符

6)标识符要尽量做到“见名知义”,增强程序的可读性。

3、数据类型

变量:

整型int 、双精度浮点型double、字符型char、字符串String、boolean类型(true or false)

注意:

1
2
3
字符串"":标识字符串
字符串用双引号:"a"(单个字符的字符串)
字符用单引号,字符串用双引号

常量:

  • 在程序运行中,值不能改变的量
  • final double PI = 3.14;
  • 优点:比较安全,后续代码不允许更改其值

注意事项

①常量名通常大写

②只能被赋值一次,通常定义时即对其进行初始化

4、运算符

赋值运算符

1
变量名 = 表达式;

算术运算符

1
2
3
+、-、*、/、%
自增++
自减--

5、类型转换

  • 自动化类型转换

①类型相容

②目标类型 > 源类型

1
2
3
double num1 = 1.2;
int num2 = 2;
double result = num1 + num2;
  • 强制类型转换

①(类型名)表达式

1
2
double a = 5.2;
int b = (int)a;

6、Scanner接收用户输入

①接收类型

1
2
3
4
5
6
Scanner input = new Scanner(System.in); 
int num = input.nextInt();//接收整数
double BoyAverage = input.nextDouble();//接收小数
String name = input.next();//接收字符串

char a = input.next().charAt(0); // 获取输入字符串的第一个字符

注意:

1
import java.util.Scanner; //Scanner类在util包中

②通过 Scanner 类的 next() 与 nextLine()方法获取输入的字符串,在读取前我们一般需要使用 hasNext() 与 hasNextLine() 判断是否还有输入的数据。

  • next():
    • 一定要读取到有效字符后才可以结束输入
    • 对输入有效字符之前的空白,next()方法会自动将其去掉
    • 只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符
    • next()不能得到带有空格的字符串
  • nextLine():
    • 以Enter为结束符,也就是说nextLine()方法返回的是输入回车之后的所有字符
    • 可以获得空白

小练习:

①next方式接收用户输入的字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class T08 {
    public static void main(String[] args) {
        //创建一个扫描器对象
        Scanner scanner = new Scanner(System.in);
        System.out.println("使用next方式接收:");
        //判断用户有没有输入
        if (scanner.hasNext()){
            //使用next方法接收
            String str = scanner.next(); //程序会等待用户输入完毕
            System.out.println("输出的内容为:"+str);
        }
        //凡是属于IO流的类,如果不关闭会一直占用资源,要养成良好的习惯用完就关掉
        scanner.close();
    }
}

②nextLine方式接收用户输入的字符串

1
2
3
4
5
6
7
8
9
public class T09 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("使用nextline方式接收:");
        String str = scanner.nextLine(); //程序会等待用户输入完毕
        System.out.println(str);
        scanner.close();
    }
}

③把输入字符串的首字母转换为大写

1
2
3
4
5
6
7
8
9
public class T07 {
    public static void main(String[] args) {
        //把输入字符串的首字母转换为大写
        Scanner input = new Scanner(System.in);
        char a = input.next().charAt(0); //charAt(0)选择接收字符串的第一个
        char Big_a = (char)(a-32);
        System.out.println(Big_a);
    }
}

④输入多个数字,并计算个数和总和,每输入一个数字用回车确认,通过输入非数字来结束输入并执行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class T10 {
    public static void main(String[] args) {
        int n = 0;
        double sum = 0;
        Scanner scanner = new Scanner(System.in);
        while(scanner.hasNextDouble()){
            double x = scanner.nextDouble();
            sum+=x;
            n++;
            System.out.println("这是你输入的第"+n+"个数字");
        }
        System.out.println(n+"个数字的和为:"+sum+",平均值为:"+(sum/n));
        scanner.close();
    }
}

7、保留小数位

三、流程控制

1、关系运算符

2、if

3、switch

①switch语句中的变量类型可以为:

  • byte、short、int或者char
  • 从Java SE 7开始,switch支持字符串String类型
  • 同时case标签必须为字符串常量或字面量

②.class文件可以用IDEA反编译

③小练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class T12 {
    public static void main(String[] args) {
        String name = "喜羊羊";
        switch(name){
            case "喜羊羊":
                System.out.println("聪明");
                break;
            case "懒羊羊":
                System.out.println("懒");
                break;
            case "沸羊羊":
                System.out.println("小丑");
            default:
                System.out.println("不是羊村的!!!");
        }
    }
}

4、while

5、for

for循环语句是支持迭代的一种通用结构,是最有效、最灵活的循环结构。

for循环执行的次数是在执行前就确定的。

语法:

1
2
3
for(初始化;布尔表达式;更新){
    //代码语句
}

快捷键:

1
2
100.for
fori

6、增强for循环

Java5引入了一种主要用于数组和集合的增强型for循环

语法:

1
2
3
for (声明语句:表达式){
    //代码句子
}

声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此时数组元素的值相等。

表达式:表达式是要访问的数组名,或者是返回值为数组的方法。

实例:

1
2
3
4
5
6
7
8
public class T13 {
    public static void main(String[] args) {
        int[] numbers={1,3,5,7,9,11};
        for (int x:numbers){
            System.out.println(x);
        }
    }
}

7、break & coutinue

break在任何循环语句的主体部分,均可用break制衡环的流程;break用于强行退出循环,不执行循环中剩余的语句。(break语句也在switch语句中使用)

continue 语句用在循环语句体中,用于终止某次循环过程,即跳过循环体中尚未执行的语句,接者进行下一次是否执行循环的判定。

8、练习

打印五行的三角形(采用分割法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class T14 {
    public static void main(String[] args) {
        for (int i=1 ; i <= 5; i++){
            for (int j = 5; j > i; j--){
                System.out.print(' ');
            }
            for (int j = 0; j < i; j++) {
                System.out.print('*');
            }
            for (int j = 1; j < i; j++) {
                System.out.print('*');
            }
            System.out.println("");
        }
    }
}

四、方法

1、什么是方法

Java方法是语句的集合,它们在一起执行一个功能

  • 方法是解决一类问题的步骤的有序组合

  • 方法包含于类或对象中

  • 方法在程序中被创建,在其他地方被引用

设计方法的原则:

方法的本意是功能块,就是实现某个功能的语句块的集合。我们设计方法的时候,最好保持方法的原子性,就是一个方法只完成1个功能,这样利于我们后期的扩展。

2、方法的定义

Java的方法类似于其它语言的函数,是一段用来完成特定功能的代码片段,一般情况下,定义个方法包含以下语法:

方法包含一个方法头和一个方法体。下面是一个方法的所有部分:

  • 修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。

  • 返回值类型:方法可能会返回值。returnValueType 是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType 是关键字void。

  • 方法名:是方法的实际名称。方法名和参数表共同构成方法签名

  • 参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
    • 形式参数:在方法被调用时用于接收外界输入的数据。
    • 实参:调用方法时实际传给方法的数据。
  • 方法体:方法体包含具体的语句,定义该方法的功能。
1
2
3
4
5
6
修饰符 返回值类型 方法名(参数类型 参数名){
    ...
    方法体  
    ...
    return 返回值;
}

3、方法调用

  • 调用方法:对象名方法名(实参列表)

  • Java 支持两种调用方法的方式,根据方法是否返回值来选择

  • 当方法返回一个值的时候,方法调用通常被当做一个值。例如:

1
int larger = max(30,40);
  • 如果方法返回值是void,方法调用一定是一条语句.
1
System.out.printLn("Hello!");

例子:

return 0; 具有终止功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    public static int compere(int num1,int num2){
        int res = 0;
        if (num1 == num2){
            System.out.println("两个数字一样大!!!");
            return 0;  //return 0; 具有终止功能
        }
        if (num1 > num2){
            res = num1;
            return res;
        }else{
            res = num2;
            return res;
        }
    }

4、方法的重载

重载就是在一个类中,有相同的函数名称,但形参不同的函数

(方法可以有无限个重名的,但要确保参数类型不同)

方法的重载的规则:

  • 方法名称必须相同

  • 参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等)

  • 方法的返回类型可以相同也可以不相同

  • 仅仅返回类型不同不足以成为方法的重载

实现理论:

方法名称相同时,编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错。

小练习:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class T21 {
    public static void main(String[] args) {
        int res = 0;
        res = Add(1.2,3);
        System.out.println(res);
        res = Add(1,5,100000);
        System.out.println(res);
    }
    public static int Add(int a, int b){
        return a+b;
    }
    public static int Add(double a, int b){
        return (int)a+b;
    }
    public static int Add(int a, int b, int c){
        return a+b;
    }
}

5、命令行传参

IDEA左下角有Terminal

1
2
3
4
5
6
7
8
9
10
11
//T21.java 的绝对路径为\untitled3\src\happy\cn\method>


javac T21.java  //编译为T21.class

java T21  //提示找不到或无法加载主类T21

返回到src目录,执行:
java happy.cn.method.T21

java happy.cn.method.T21 this is a param  //传参

6、可变参数

  • JDK 1.5开始,Java支持传递同类型的可变参数给一个方法
  • 在方法声明中,在指定参数类型后加一个省略号(…)

  • 注意:
    • 一个方法中只能指定一个可变参数
    • 它必须是方法的最后一个参数,任何普通的参数必须在它之前声明。
1
public static void proMax(double... numbers){}

7、递归

  • 递归结构包括两个部分

    • 递归头: 什么时候不调用自身方法。如果没有头,将陷入死循环

    • 递归体: 什么时候需要调用自身方法

注意:

要有 边界条件(边界)、前阶段、返回阶段(n*(n-1))、

小计算可以用递归,大计算GG

五、数组

1、定义

  • 数组是相同类型数据的有序集合

  • 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成

  • 其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们

2、声明创建

语法:

1
2
3
dataType[] arrayRefVar;  //首选的方法
或
dataType arrayRefVar[];  //效果相同,但不是首选方法

Java语言使用new操作符来创建数组,语法如下:

1
2
3
dataType[] arrayRefVar = new dataType[arraySize];

int[] nums = new int[20];

获取数组长度

1
2
3
4
array.length

int[] nums = new int[20];
len = nums.length

赋值

1
2
nums[0] = 1;
nums[1] = 2;

3、内存分析

Java内存

①声明数组时,栈中压入一个array,堆中没有东西

1
int[] nums = null;

image-20241023162334438

②创建数组时,会在堆中开辟一块空间

1
nums = new int[10];

image-20241023162511475

③给数组赋值时,会在堆开辟的空间中,填入相应的值

image-20241023162536675

4、三种初始化

  • 静态初始化:创建+赋值
1
2
int[] a = {1,2,3};
Man[] mans = {new Man(1,1),new Man(2,2)};
  • 动态初始化:包含默认初始化
1
2
3
int[] a = new int[2];
a[0] = 1;
a[1] = 2;

数组的每个元素有默认值。

  • 数组的默认初始化
    • 数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。

5、四个基本变量

  • 其长度是确定的。数组一旦被创建,它的大小就是不可以改变的
  • 其元素必须是相同类型,不允许出现混合类型。
  • 数组中的元素可以是任何数据类型,包括基本类型和引用类型
  • 数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量
  • 数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的

6、数组边界

下标的合法区间:[0,length - 1],如果越界就会报错

7、小结:

  • 数组是相同数据类型(数据类型可以为任意类型)的有序集合

  • 数组也是对象。数组元素相当于对象的成员变量

  • 数组长度的确定的,不可变的。如果越界,则报: ArraylndexOutofBounds

8、数组使用

  • 普通的For循环
  • For-Each 循环
  • 数组作方法入参
  • 数组作返回值

9、多维数组

多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组。

1
2
int a[][] = new int[2][5];
//二维数组a可以看成一个两行五列的数组。

image-20241023175149934

10、Array类

  • 数组的工具类java.util.Arrays,此类包含用于操作数组的各种方法(如排序和搜索)

  • 由于数组对象本身并没有什么方法可以供我们调用,但API中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本的操作。

  • 查看JDK帮助文档

  • Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而”不用“使用对象来调用

    (注意:是”不用”而不是“不能”)

具有以下常用功能:

  • 给数组赋值:通过 fill 方法

  • 对数组排序:通过 sort 方法按升序

  • 比较数组:通过equals 方法比较数组中元素值是否相等

  • 查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作
  • ………

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package happy.cn.array;
import java.util.Arrays;

public class T32 {
    public static void main(String[] args) {
        int[] a = {1,2,3,4,324,6547,757,645,31};
        //打印数组元素Arrays.toString
        System.out.println(Arrays.toString(a));

        //对数组进行排序
        Arrays.sort(a);
        System.out.println(Arrays.toString(a));

        //数组填充:把数组的每一项都填乘1
        Arrays.fill(a,2);
        System.out.println(Arrays.toString(a));
    }
}

11、冒泡排序

冒泡排序无疑是最为出名的排序算法之一,总共有八大排序

冒泡的代码还是相当简单的,两层循环,外层冒泡轮数,里层依次比较,江湖中人人尽皆知.

我们看到嵌套循环,应该立马就可以得出这个算法的时间复杂度为O(n2)。

练习:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package happy.cn.array;
import java.util.Arrays;

public class T33 {
    public static void main(String[] args) {
        int[] nums = {12,35,21,11,34,22,35,5474,325,36,457,232,5345,42,24,1};
        int c = 0;
        //从小到大 冒泡排序
        for (int i = 0; i < nums.length - 1; i++) {
            for (int j = 0; j < nums.length - 1 -i; j++){
                if (nums[j] > nums[j+1]){
                    c = nums[j];
                    nums[j] = nums[j+1];
                    nums[j+1] = c;
                }
            }
        }
        System.out.println(Arrays.toString(nums));
    }
}

优化:减少了冒泡的次数,加快运行时间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package happy.cn.array;
import java.util.Arrays;

public class T33 {
    public static void main(String[] args) {
        int[] nums = {1,2,3,5,6,7,8,9};
        int s = 0; //冒泡次数
        int c = 0;
        //从小到大 冒泡排序
        for (int i = 0; i < nums.length - 1; i++) {
            boolean flag = false; //优化:这里弄一个标识位
            for (int j = 0; j < nums.length - 1 -i; j++){
                if (nums[j] > nums[j+1]){
                    c = nums[j];
                    nums[j] = nums[j+1];
                    nums[j+1] = c;
                    s++;
                    flag = true; //如果有数字交换的话,flag为true标准着还要继续循环冒泡/
                }
            }
            if (flag == false){
                System.out.println("okk,到这里就不需要继续冒泡了,因为已经从小到大排序了!");
                break;
            }
        }
        System.out.println(Arrays.toString(nums));
        System.out.println("一共冒泡了"+s+"次");
    }
}

12、稀疏数组

  • 当一个数组中大部分元素为0,或者为同一值的数组时,可以使用稀疏数组来保存该数组

  • 稀疏数组的处理方式是:
    • 记录数组一共有几行几列,有多少个不同值
    • 把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模
  • 稀疏数组就是记录原始数组的坐标、值

如图:

image-20241024112708315

练习:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package happy.cn.array;

import java.sql.Array;

public class T34 {
    public static void main(String[] args) {
        //1、先造一个二维数组
        int[][] array1 = new int[11][11];
        array1[1][2] = 1;
        array1[2][3] = 2;
        //2、打印出来
        for (int[] nums : array1){
            for (int num : nums){
                System.out.print(num+"\t");
            }
            System.out.println();
        }
        System.out.println("========================================");
        //3、转换为稀疏数组
            //①先统计有效值
        int amount = 0;
        for (int i = 0; i < array1.length; i++) {
            for (int j = 0; j < array1[i].length; j++) {
                if (array1[i][j] != 0){
                    amount++;
                }
            }
        }
        System.out.println("有效值的个数为:"+amount);
            //②根据有效值的个数,创建稀疏数组的大小
        int[][] array2 = new int[amount+1][3]; //行数为:有效值个数 + 1,因为第一行分别为原数组的行数、列数、有效值个数(为真实行数、列数)
        array2[0][0] = 11;
        array2[0][1] = 11;
        array2[0][2] = amount;
            //③遍历原数组,把有效值的坐标行数、坐标列数、值填入稀疏数组中(这里的行数、列数是有效值在原数组中的坐标)
        int row = 1; //稀疏数组的坐标行数,因为坐标行数0,已经填了原数组的信息
        for (int i = 0; i < array1.length; i++) {
            for (int j = 0; j < array1[i].length; j++) {
                if (array1[i][j] != 0){
                    array2[row][2] = array1[i][j]; //值
                    array2[row][0] = i; //坐标行数
                    array2[row][1] = j; //坐标列数
                    row++;
                }
            }
        }
        //4、打印完成后的稀疏数组
        for (int[] nums : array2){
            for (int num : nums){
                System.out.print(num+"\t");
            }
            System.out.println();
        }
        System.out.println("========================================");
        //5、还原为原数组
        int[][] array3 = new int[array2[0][0]][array2[0][1]]; //还原原数组的大小
        for (int i = 1; i < array2.length; i++) {
            for (int j = 0; j < 3; j++) {
                array3[array2[i][0]][array2[i][1]] = array2[i][2];
            }
        }
        //6、打印处还原后的数组
        for (int[] nums : array3){
            for (int num : nums){
                System.out.print(num+"\t");
            }
            System.out.println();
        }
    }
}

六、面向对象

属性+方法 = 类

1、面向过程&面向对象

  • 面向过程思想
    • 步骤清晰简单,第一步做什么,第二步做什么…
    • 面对过程适合处理一些较为简单的问题
  • 面向对象思想
    • 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。
    • 面向对象适合处理复杂的问题,适合处理需要多人协作的问题
  • 对于描述复杂的事物,为了从宏观上把握,从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路区处理。

2、面向对象

  • 面向对象编程(Object-Oriented Programming,OOP)

  • 面向对象编程的本质就是: 以类的方式组织代码,以对象的形式组织(封装)数据
  • 抽象
  • 三大特性:封装、继承、多态
  • 从认识论角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象。
  • 从代码运行角度考虑是先有类后有对象。类是对象的模板。

3、方法回顾

没有返回类型,也要return;

1
2
3
public void hello(){
    return;
}

方法的定义

  • 修饰符
  • 返回类型
  • break:跳出switch,结束循环 和 return的区别
  • 方法名:注意规范就OK 见名知意
  • 参数列表:(参数类型,参数名)…
  • 异常抛出:疑问,后面讲解

static:静态方法。类名.方法名可以直接调用

image-20241104211525860

非静态方法:不能这样(类名.方法名)调用。用new

image-20241025130359325

这里的对象值变为实例化对象

都没有statc,a可以调用b;

都有static,a可以调用b;

a有static,b没有,a不能调用b

1
2
3
4
5
6
7
8
9
//和类一起加载的
public static void a(){  
    b();
}
//类实例化之后才存在
public void b(){
    
}
//已经存在的东西,调用不存在的东西会报错。所以a有static,b没有时,a不能调用b

这个例子就是实例化一个类之后,用方法给类的属性赋值

image-20241025133153863

4、类与对象的创建

规范:一个项目应该只存在一个main方法

类里面有 属性 和 方法

image-20241104214811514

5、构造器详解

  • 使用new关键字创建对象
  • 使用new关键字创建的时候,除了分配内存空间之外。还会给创建好的对象进行默认的初始化,以及对类中构造器的调用
  • 类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下两个特点:
    • 1、必须和类的名字相同
    • 2、必须没有返回类型,也不能写void
  • 构造器必须要掌握

一个类即使什么也不写,它也会存在一个方法

显示的定义构造器:

1
2
3
public class Person{
    public Person(){}
}

作用:

①实例化初始值

②使用new关键字,本质是在调用构造器

注意

定义了有参构造之后,如果想使用无参构造,需要显式的定义一个无参构造。

IDEA构造器的快捷键

这里是绿色小tips的内容。

6、创建对象内存分析

image-20241107165402199

static:和类一起加载

左边是栈,右边是堆

7、简单小结类与对象

image-20241107194207564

4、默认初始化:

  • 数字:0 0.0
  • char:u0000
  • boolean:false
  • 引用:null

8、封装详解

image-20241107204354356

作用:

  • 提高程序的安全性,保护数据
  • 隐藏代码的实现细节
  • 统一接口
  • 系统的可维护增加了

9、继承

  • 继承的本质是对某一批类的抽象,从而时间对现实世界更好的建模
  • extends的意思是“扩展”。子类是父类的扩展
  • Java中类只有单继承,没有多继承。(一个父亲可以有多个儿子,一个儿子只能有一个父亲)
  • 继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。
  • 继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键词extends来表示。
  • 子类和父类之间,从意义上讲应该具有“is a”的关系
  • 在Java中,所有类,都默认之间或者间接继承Object类
查看当前选定类的层次结构的快捷键

Ctrl+H

可以打开 “Type Hierarchy”(类型层次结构)窗口。在这个窗口中,可以看到当前选定类的层次结构,包括它的父类、子类以及实现的接口。

image-20241107205835167

10、Super详解

注意

私有的东西无法被继承 调用父类的构造器,必须要在子类构造器的第一行

image-20241107220053571

image-20241107220112285

父类是有参构造那就调用有参构造

image-20241107220413552

总结:

  • super注意点:
    • super调用父类的构造方法,必须在构造方法的第一个
    • super必须只能出现在子类的方法或者构造方法中
    • super和this不能同时调用构造方法
  • super和this对比:
    • 代表的对象不同:
      • this:本身调用者这个对象
      • super:代表父类对象的应用
    • 前提
      • this:没有继承也可以使用
      • super:只能在继承条件里才可以使用
    • 构造方法
      • this();本类的构造
      • super():父类的构造

11、方法重写

image-20241108150316557

重写演示:

image-20241108150909265

注意

非静态方法才能重写 重写关键词只能是public

需要有继承关系,子类才能重写父类的方法

  • 方法名必须相同
  • 参数列表必须相同
  • 修饰符:范围可以扩大但不能缩小:public > protected > default > private
  • 抛出的异常:范围,可以被缩小,但不能扩大:ClassNotFoundException –> Exception(大)

重写,子类的方法和父类必须一致:方法体不同

为什么要重写:

  • 父类的功能,子类不一定需要,或者不一定满足
快捷键

Alt + Insert ; override;

12、什么是多态

即一个方法可以根据发送对象的不同而采用多种不同的行为方式

一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多(父类,有关系的类)

多态存在的条件

  • 有继承关系
  • 子类重写父类方法
  • 父类引用指向子类对象
注意

多态是方法的多态,属性没有多态性

父类型,可以指向子类,但是不能调用子类独有的方法 对象能执行哪些方法,主要看对象左边的类型,和右边关系不大

image-20241108164250484

强制类型转换(高转低)

image-20241108164418841

13、instanceof

测试它左边的对象是否是它右边的类的实例,返回 boolean 的数据类型。

image-20241108171037773

image-20241108172953274

1、父类引用指向之类的对象

2、把子类转换成父类,向上转型(可能会丢失自己本来的一些方法)

3、把父类转换成子类,向下转型(强制转换)

4、方便方法的调用,减少重复的代码(简洁)

14、static关键词详解

匿名代码块

静态代码块

image-20241108174739657

static代码块只执行一次

静态导入包

image-20241108175124897

15、抽象类

image-20241108175618120

继承了抽象类的子类,要实现抽象类的所有方法,除非子类也是抽象类

image-20241108175701904

接口可以多继承

类是单继承的

注意

1、不能new这个抽象类,只能靠子类去实现它:约束

2、抽象类种可以写普通的方法

3、抽象方法必须在抽象类中(有抽象方法的一定是抽象类)

16、接口

image-20241108185113265

声明类的关键字是class。声明接口的关键字是interface

智能的IDEA:

  • Action为抽象类
  • A为正常类
  • UserService为接口

image-20241108185340742

接口中的所有定义其实都是抽象的public abstract

1
2
3
4
public abstract void run(String name);

可以写成
void run(String name);

image-20241108185612207

接口的实现用implements,需要重写接口中的方法

image-20241108185750530

接口可以实现多继承

image-20241108185832893

接口的作用:

1、约束

2、定义一些方法,让不同的人实现

3、接口中定义的方法,都是public abstract

4、接口中定义常量:public static final

5、接口不能被实例化,接口中没有构造方法

6、implements可以实现多个接口

7、必须要重写接口中的方法

17、N种内部类

image-20241108191302128

类套类

image-20241108191708268

内部类可以获得外部类的私有属性、私有方法

静态内部类

image-20241108192216214

一个Java类里面只能有一个public class ,但可以有多个class

image-20241108192345294

方法里面也可以写类

image-20241108192600991

匿名对象的使用

七、异常

1、Error和Exception

image-20241114162717565

简单分类

检查性异常、运行时异常、错误ERROR

image-20241108194144942

异常体系结构

image-20241108194254337

image-20241108194524248

2、捕获和抛出异常

五个关键字:

try、catch、finally、throw、throws

可以捕获多个异常

finally可以不写

如果要捕获多个异常,异常的范围应该从小到大写

image-20241108195957504

自动生成捕获快捷键

选中,trl Alt T

image-20241108200107924

打印错误栈信息

1
e.printStackTrace();

image-20241108200315708

主动抛出异常

  • 一般在方法中使用

image-20241108200805975

用了try catch,不会停止,程序会继续运行下去

上抛出异常后,被catch

3、自定义异常

image-20241109164047239

test()上抛之后在main()里面被catch

image-20241109164107359

实际应用中的经验总结

image-20241109164548071

八、JavaSE总结

image-20241109175800460

image-20241109180257232

image-20241109180527455

image-20241109181208849

image-20241109182638071

image-20241109182822715

#### JavaDoc

image-20241109183359776

image-20241109190407662

1
Javadoc -encoding UTF-8 -charset UTF-8 HelloWorld.java

流程控制

image-20241109184133733

方法

image-20241109190634281

main方法传参数

image-20241109190407662

image-20241109190431043

数组

image-20241109191045651

面向对象

image-20241109191746562

image-20241109192008020

image-20241109192153585

异常

image-20241109192651195

本文由作者按照 CC BY 4.0 进行授权