java入门

流程控制

用户交互Scanner

  1. 输入&输入方法(比如是输入hello world)

    • next()输入字符串不能存在空格 (输出hello)

    • nextLine(),回车前的所有字符,可以获取到空格 (输出hello world)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      package xxxxx.xxx.xxx
      import java.util.Scanner;
      public class Demo03 {
          public static void main(String[] args) {
              // 从键盘接收数据
              Scanner scanner = new Scanner(System.in);
              System.out.println("请输入数据:");
              String str = scanner.nextLine();
              System.out.println("输出的内容为:"+str);
              scanner.close();
          }
      }
  2. 判断

    1
    2
    3
    4
    5
    6
    if (scanner.hasNextInt()) {    //这个条件是判断 输入是不是整数的
        i = scanner.nextInt();
        System.out.println("整数数据:" + i);
    } else {
        System.out.println("输入的不是整数数据:" + i);
    }

    判断字符串有函数:
    x.equal(“xcsccsc”) 判断x输入字符串和xcsccsc字符串是否相等

判断

  1. if

    • 单层–if

      1
      2
      3
      if(){
          System.out.println("*****")
      }
    • 两层–if else

      1
      2
      3
      4
      5
      if(){
          System.out.println("*****")
      }else(){
          System.out.println("*****")
      }
    • 多层–if else if else

      1
      2
      3
      4
      5
      6
      7
      8
      9
      if(){
          System.out.println("*****")
      }else if(){
          System.out.println("*****")
      }else if(){
          System.out.println("*****")
      }else(){
          System.out.println("*****")
      }
  2. switch case

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    switch(expression){
        case value :
            //语句
            break; //可选
        case value :
            //语句
            break; //可选
        //你可以有任意数量的case语句
        default : //可选
            //语句
    }

    注意:

    • switch变量类型:byte short int char string(java7以后)
    • case变量类型:字符串常量 自变量
    • case穿透:不写break就在条件后全执行

循环

  1. while

    1
    2
    3
    while(布尔值){
        
    }

    注意要写退出循环的限制条件,不然会变成死循环

    eg:i++;

  2. do while

    1
    2
    3
    do{
        
    }while();//注意有分号
  3. for

    1
    2
    3
    for(初始化(可以空);布尔表达式;更新){//分号隔开
        代码语句
    }

    在idea里面,写100.for可以直接生成

  4. 增强for

    1
    2
    3
    4
    5
    6
    7
    8
    public class ForDemo05 {
        public static void main(String[] args) {
            int[] numbers = {10,20,30,40,50}; //定义了一个数组
            for (int x:numbers){
                System.out.println(x);
            }
        }
    }

    遍历数组,每次for循环输出

  • While和do-While的区别:]

    while先判断后执行。dowhile是先执行后判断!

    Do…while总是保证循环体会被至少执行一次!这是他们的主要差别

  • break&&continue

    break用于强制退出循环,不终止程序(放在判断后)

    continue只是这一次不执行,下一次继续执行

    (goto在java不存在)但是可以利用标签使用,起跳转作用

方法

基础

方法类似于函数

  • System.out.printIn()
    类.对象.方法

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

    • 方法是解决一类问题的步骤的有序组合
    • 方法包含于类或对象中
    • 方法在程序中被创建,在其他地方被引用
1
2
3
4
5
6
7
8
9
10
public class Demo01{
    //main方法
    public static void main(string[]args){
        int sum=add(a:1,b:2);System.out.println(sum);
    }
	//加法
    public static int add(int a,int b){
        return a+b;
    }
}

在写方法的时候public int add(int a,int b),要想调就要加一个static

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

    可以多用写一些方法,把main函数变得更加简洁

1
2
3
4
5
6
修饰符 返回值类型 方法名(参数类型 参数名){
    ...
    方法体
    ....
    return 返回值;//有返回类型,一定要写return
}

调用

  • 当方法返回一个值的时候,方法调用通常被当做一个值
  • 如果方法返回值是void,方法调用一定是一条语句

重载

函数名称相同,参数类型不同(返回值是谁,就调用谁)

参数类型也可以相同,在方法里面强制转化就行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//比大小
public static int max(double num1,double num2){
    int result = 0;
    if (num1==num2){
        System.out.println("num1==num2");
        return 0; //终止方法
    }
    if (num1>num2){
        result = (int)num1;
    }else {
        result = (int)num2;
    }
    return result;
}

但是在调用的时候,要调配和方法相匹配,要不编译器会报错

命令行传参

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
71
72
73
public class CommandLine {
    public static void main(String args[]){
        for(int i=0; i<args.length; i++){
            System.out.println("args[" + i + "]: " + args[i]);
        }
    }
}
```

![image-20251022090113344](https://cdn.jsdelivr.net/gh/zhz0177/picture-bed@main/img/20251027125533446.png)

直接在idea里面的命令行运行不成功,所以打开方法-所在文件夹,使用命令行编译,发现还是不行

因为运行需要在src目录下,回退完目录后,再次运行

源码定义的是一个数组,所以在语句后面跟上参数`this is kuangshen`

发现成功返回

**也就是说main方法也是可以传参的**

## 可变参数

本质就是一个数组

- JDK 1.5 开始,Java支持传递同类型的可变参数给一个方法。、
-   在方法声明中,在指定参数类型后加一个省略号(...)  
- 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明

```java
public class Demo04 {
    public static void main(String[] args) {
        Demo04 demo04 = new Demo04();
        demo04.test(1,2,3,4,45,5);
    }

    public void test(int... i){
        System.out.println(i[0]);
        System.out.println(i[1]);
        System.out.println(i[2]);
        System.out.println(i[3]);
        System.out.println(i[4]);
        System.out.println(i[5]);
    }
}
```

## 递归

自己调用自己

简单来说就是找到公式规律,然后往前一个未知数推导(复杂问题,简单化,减少重复计算,减少代码量)

- 递归结构包括两个部分:

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

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

java主要使用的是栈,就是罐子里面一个叠一个,**先放后拿** 

## 静态&非静态

- 静态:有static

  在其他类里面写,可以在main里面调用 `类.方法`

- 非静态:

  调用:将类实例化new--------->对象类型  对象名=对象值

  ```java
  Student student =new student();

image-20251022215227014

调用

  • 有static,和类一起加载,存在较早
  • 无static,在类实例化之后才存在,比上面那个迟

所以不能在有static,调用无static的方法

image-20251022215527356

b()明显报错了

数组

定义一组类型,相同类型的有序集合,通过下标访问

定义

1
2
3
4
public static void main(stringl args){
    int[] nums; //1.定义
    int nums2[];//2.c和c++使用的多
}

没定义,返回默认值(int 的默认值就是0)

获取数组长度是arrays。length

初始化

  • 静态初始化

    1
    2
    3
    // 静态初始化: 创建 + 赋值
           int[] a = {1,2,3,4,5,6,7,8};
           System.out.println(a[0]);
  • 动态初始化(包含默认初始化)

    先分配内存(初始化)(变成默认值),再赋值

    1
    2
    3
    // 动态初始化 : 包含默认初始化
           int[] b = new int[10];
           b[0] = 10;
  • 数组的默认初始化

    就是分配内存的初始化

内存分析

  1. 堆
  2. 栈
  3. 方法区
1
2
3
4
5
6
7
8
步骤 1:声明数组
代码int[] array = null;声明了一个整型数组变量array,并将其初始化为null,表示该数组目前没有指向任何实际的数组对象

步骤 2:创建数组
代码array = new int[10];创建了一个长度为 10 的整型数组,并将其引用赋值给array变量,此时数组的每个元素都有了默认值(整型数组默认值为 0)

步骤 3:给数组元素赋值
代码通过类似nums[0] = 1;这样的语句(这里变量名可能存在笔误,应为array),给数组的每个元素依次赋值,从array[0]到array[9]分别赋值为 1 到 10

先声明空数组(栈),在new一个数组(在堆内部分配空间),然后赋值(赋值)

image-20251022153931969

特点

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

使用

  • 打印所有的数组元素

    1
    2
    3
    for (int i = 0; i < arrays.length; i++) {
                System.out.println(arrays[i]);
            }
  • 计算sum

    1
    2
    3
    4
    5
    int sum = 0;
          for (int i = 0; i < arrays.length; i++) {
              sum += arrays[i];
          }
          System.out.println("sum=" + sum);
  • 寻找max

    1
    2
    3
    4
    5
    6
    7
    8
    int max = arrays[0];
            for (int i = 1; i < arrays.length; i++) {
                if (arrays[i] > max) {
                    max = arrays[i];
                }
            }
            
        }
  • 增强for循环

    快捷语句:array.for 省略了数组下标

    1
    2
    3
    for(int array  :  array){//int array相当于下标,array相当于这个数组
        System.out.println(array);
    }
  • 分装成方法的参数//数组作为返回值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    //打印数组
    public static void printArray(int[] arrays){
            for (int i = 0; i < arrays.length; i++) {
                System.out.print(arrays[i] + " ");
            }
        } 
    
    //反转数组 
    public static int[] reverse(int[] arrays){
        int[] result = new int[arrays.length];
    
        //反转的操作
        for (int i = 0,j=result.length-1; i < arrays.length; i++,j--) {
            result[j] = arrays[i];
        }
    
        return result;
    }
  • 多维数组

    数组的多重嵌套

    1
    2
    3
    4
    5
    6
    //输出二维数组
    for (int i = 0; i < array.length ; i++) {
                for (int j = 0; j < array[i].length ; j++) {
                    System.out.println(array[i][j]);
                }
            }
    • 第一个条件 i < array.length 是限制行下标 i 的,array.length 表示二维数组的行数,确保 i 不会超出行的范围。
    • 第二个条件 j < array[i].length 是限制列下标 j 的,array[i].length 表示第 i 行的列数,确保 j 不会超出当前行的列范围。

应用

  1. arrays类

    • 数组的工具类java.util.Arrays
    • 由于数组对象本身并没有什么方法可以供我们调用,但API中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本的操作。
    • 查看JDK帮助文档
    • Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而”不用“使用对象来调用(注意:是”不用”而不是“不能”)
    • 具有以下常用功能:
      ◆给数组赋值:通过 fi 方法。
      ◆对数组排序:通过 sort 方法,升序,
      ◆比较数组:通过 equals 方法比较数组中元素值是否相等
      ◆查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作。
  2. 冒泡排序(两层循环)

    两两相邻比较,出现大小差异就交换顺序

    每次比较都会出现max和min,下一轮就减少一次循环

    依次循环,直到结束

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    public static int[] sort(int[] array){
        //临时变量
        int temp = 0;
    
        //外层循环,判断我们这个要走多少次;
        for (int i = 0; i < array.length-1; i++) {
            //内层循环,比价判断两个数,如果第一个数,比第二个数大,则交换位置
            for (int j = 0; j < array.length-1-i ; j++) {
                if (array[j+1]>array[j]){
                    temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                }
            }
        }
    
        return array;
    }
  3. 稀疏数组

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

    • 稀疏数组的处理方式是:

      ◆记录数组一共有几行几列,有多少个不同值
      ◆把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模

    image-20251022164858914

    左边是原始数组,右边是压缩数组

    • 共六行七列(除去0),只有8个有效数字——->初始数组都是0(初始化)
    • 后面就是坐标定位有效值 ——->赋值替换有效值

面向对象(op)

对比

面向对象 vs 面向过程

  • 面向对象:是线性的(第一步,第二步这样)——>框架
  • 面向过程:是分类思维(分类进行独立思考)——>流程

定义

面尚对象编程的本质就是:以类的方式组织代码,以对象的组织(封装)数据

三大特性:封装 继承 多态

从认识论角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象

从代码运行角度考虑是先有类后有对象。类是对象的模板。

类与对象的关系

  1. 一个项目应该只存在一个main方法

  2. 一个类里面,只有可能存在属性和方法这俩东西

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //学生类
    public class Student {
        //属性:字段
        String name;//默认值nell
        int age;//默认值0
    
        //方法
        public void study(){
            System.out.println(this.name+"在学习");
        }
    }

    this.name指的是在这个类里面的属性

  3. 类——->对象 抽象——->实例

    先输入 new 类名()(如 new Student()),然后使用快捷键 **Ctrl + Alt + V**,IDEA 会自动生成变量声明语句(如 Student student = new Student();)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    public class Demo03 {
        public static void main(String[] args) {
            //类:抽象的,实例化
            //类实例化后会返回一个自己的对象!
            //student对象就是一个Student类的具体实例!
            
    	Student xiaoming = new Student();//Student student = new student();
    	Student xh = new Student();//Student student = new student();
    
    	xiaoming.name = "小明";
        xiaoming.age = 3;
    
    	System.out.println(xiaoming.name);
    	System.out.println(xiaoming.age);
    
    	System.out.println(xh.name);
    	System.out.println(xh.age);
    }

    结合上面写的,xiaoming.name = “小明”; xiaoming.age = 3;这个对象已经赋值,所以返回赋值内容

    xh这个对象并没有赋值,所以返回默认值

构造器

生成alt+insert

1
2
3
4
5
6
7
8
9
10
11
12
//java ---> class
public class Person {

    //一个类即使什么都不写,它也会存在一个方法
    //显示的定义构造器
    String name;

    //实例化初始值
    public Person(){
        this.name = "小明";
    }
}
1
2
3
4
5
6
7
8
9
10
//一个项目应该只存一个main方法
public class Application {

    public static void main(String[] args) {
        //new 实例化了一个对象
        Person person = new Person();//////如果在里断点

        System.out.println(person.name); //aaaa
    }
}

使用断点检测:

  1. 没走就是null
  2. 先到类里面的public Person
  3. 后面赋值”小明”(赋值是person类里面的 String name;)
  4. 接着再次回到new
  5. 然后接着往下走

作用:

  • 使用new关键字,不质是在调用构造器
  • 用来初始化值

构造器:
1.和类名相同
2.没有返回值
作用:
1.new 本质在调用构造方法
2.初始化对象的值
注意点:
1.定义有参构造之后,如果想使用无参构造,显示的定义一个无参的构造
2.alt+insert
3.this.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1.类
2.方法
3.引用类型:基本类型(8)对象是通过引用来操作的:栈--->堆
4.属性:字段Field 成员变量
默认初始化:
数字:8
0.8
u0000char :
boolean:false
引用:null
修饰符 属性类型 属性名= 属性值!
5.对象的创建和使用
-必须使用new 关键字创造对象,构造器 Person kuangshen = new Person();-对象的属性kuangshen.name对象的方法kuangshen.sleep()
类:静态的属性动态的行为

理解:

构造器随着对象创建而直接调用,而使用方法还得手动调用

(就像,人出生就伴随的 身份证号码,是否在呼吸;但是跑步,游泳是可选择的)

封装

  • 该露的露,该藏的藏

  • 我们程序设计要追求“高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用。

  • 封装(数据的隐藏):
    通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏

属性私有,get/set

image-20251024164516243

private私有属性之后,在main里面调用就会报错

public就不会

如何调用:

get/set(快捷键alt+insert)

1
2
3
4
5
6
7
8
9
public class Application {
    public static void main(String[] args) {
        Student s1 = new Student();
        s1.setName("秦疆");
        System.out.println(s1.getName());
        s1.setAge(-1);//不合法的
        System.out.println(s1.getAge());
    }
}

get用于Application的调用后的输出,set用于调用赋值

意义:

  • 提高程序的安全性,保护数据

    也可以直接在封装内部附加条件,对不合法信息进行过滤

  • 隐藏代码的实现细节

    封装之后看不到,数据隐藏

  • 统一接口

    只使用get和set接口

  • 系统可维护增加了

理解为什么要封装:

使用有if的public方法&&使用内部if的private

public:有条件,可以不走条件,公开属性可以修改(绕过过滤)

private:有条件,必须走条件,不合法只能被拦截

比如:

  • public你家大门上挂了个 “请按门铃” 的牌子,大门没锁
    • 有素质的人会按门铃
    • 但没素质的人可以直接推门而入,牌子形同虚设
  • private想进门必须按门铃(必须调用方法),想绕都绕不过去

重载

比如println可以输出许多东西

步入方法就会知道,写了 许多相同方法名的不同参数的方法

image-20251024172431860

继承

  • 继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。

  • extends的意思是“扩展”。子类是父类的扩展

  • JAVA中类只有单继承,没有多继承!(但是可以通过接口实现)(想了解的直接跳的接口标题查看)

    一个儿子一个爹;一个爹好几个儿子

    ◆ 继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等

    ◆ 继承关系的俩个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示,

    ◆ 子类和父类之间,从意义上讲应该具有”is a”的关系.

    ◆ 子类可以继承父类的所有方法

    ◆ 子类无法继承父类private

    但是可以通过get/set通过一些特定条件来调用(不能继承,但是留了点接口;不能让你随便花钱,但是可以给你留点)

1
2
3
public class  Person{
    
}
1
2
3
public class Student extends Person{
    
}

学生 是 人(student继承 person)

感觉像是树形图(ctrl+H可以打开继承树)

  • 也可以组合:

    1
    2
    3
    public class Student {
        Person person;
    }
  • 父类上面,还有object:

    因为object是所有类的父类,所有的类,都默认直接或者间接继承object

Super

  • Super对比this

    image-20251024174447756

    1
    2
    3
    System.out.println(name); // 输出方法的传参参数
    System.out.println(this.name); // 输出当前类的成员变量
    System.out.println(super.name); // 输出父类的成员变量
  • 类内部有默认的构造器
    在的父类写构造器,写输出
    在子类写构造器,写输出
    在所在类内部new一个子类,执行发现:先输出父类,在输出子类
    也就是说,存在隐藏代码,就是调用父类的构造器

    如果父类是有参的,子类是无参的
    new一个对象发现,调用不了(父类不能用,子类也不能用)

  • 总结

    • super注意点:
      1.super调用父类的构造方法,必须在构造方法的第一个

      2.super 必须只能出现在子类的方法或者构造方法中!

      3.super和 this 不能同时调用构造方法!

      ​ 因为这两个都要放在第一行,一起用就冲突了

    • Vs this:
      代表的对象不同:
      this:本身调用者这个对象

      super:代表父类对象的应用

      前提:
      this:没有继承也可以使用
      super:只能在继承条件才可以使用

      构造方法:

      this():本类的构造
      super():父类的构造!

重写

是方法的重写,和属性无关

  • 有static的情况

    image-20251024211537644

    父类有text方法,子类也有text方法

    调用时,A和B方法不同,但是父类的引用指向了子类

    静态方法不支持重写

    这不是 “方法重写”,(因为静态方法不支持重写,只是 “子类定义了同名静态方法)

  • 无static

    而且重写的关键词只能是public不能是private

    而且还会出现注释 @Override

    image-20251024212744560

    相当于子类重写了父类的方法

    第一个输出是子类的

    第二个输出还是子类(B b = new A() 父类被重写)

总结:

重写:需要有继承关系,子类重写父类的方法!
1.方法名必须相同
2.参数列表列表必须相同
3.修饰符:范围可以扩大但不能缩小 public>Protected>Default>private
4.抛出的异常:范围,可以被缩小,但不能扩大: classNotFoundException (小)—–>Exception(大)
重写,子类的方法和父类必要一致;方法体不同!

为什么需要重写:
父类的功能,子类不一定需要,或者不一定满足

重写 VS 重载:

image-20251024213257448

多态

其实上面说的重写就是体现多态

为了让子类能够根据自身特性 “定制” 父类的行为,从而让代码更灵活、更贴合场景

就是我在上面写的 有static的情况 和 无static的这两种

注意事项:

  1. 多态是方法的多态,属性没有多态
  2. 父类和子类,有联系 类型转换异常!ClassCastException!
  3. 存在条件: 继承关系,方法需要重写,父类引用指向子类对象! Father f1 = new Son ();

不能重写的:

  1. static 方法,属于类,它不属于实例
  2. final 常量;
  3. private 方法;

instanceof和类型转换

  • instanceof

    (类型转换) 引用类型,判断一个对象是什么类

    满足父子关系就是ture 否则就是false

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public static void main(String[] args) {
        //Object > String
        //Object > Person > Teacher
        //Object > Person > Student
        Object object = new Student();
    
        System.out.println(object instanceof Student); //true
        System.out.println(object instanceof Person); //true
        System.out.println(object instanceof Object); //true
        System.out.println(object instanceof Teacher); //False
        System.out.println(object instanceof String); //False
    }

    如果将object变成Person

    1
    2
    3
    4
    5
    System.out.println(Person instanceof Student); //true
       System.out.println(Person instanceof Person); //true
       System.out.println(Person instanceof Object); //true
       System.out.println(Person instanceof Teacher); //False
       System.out.println(Person instanceof String); //编译报错(Person和String是同级的)

    换成Student

    1
    2
    3
    4
    5
    System.out.println(Student instanceof Student); //true
       System.out.println(Student instanceof Person); //true
       System.out.println(Student instanceof Object); //true
       System.out.println(Student instanceof Teacher); //编译报错
       System.out.println(Student instanceof String); //编译报错(Person和String是同级的)
  • 强制转化

    在Person类里面有run(父)
    在Student类里面有go(子)
    想要 对象 调用go就要 Perso类型强制转化为Student类型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    public class Application {
        public static void main(String[] args) {
            //类型之间的转化: 父  子
            //高                低
            Person obj = new Student();
            //student将这个对象转换为Student类型,我们就可以使用Student类型的方法了!
            Student student = (Student) obj;
            student.go();
        }
    }
    1
    (Student) obj.go();//或者直接这样

总结:

  1. 父类引用指向子类的对象
  2. 把子类转换为父类,向上转型(子类的方法可能会部分丢失)
  3. 把父类转换为子类,向下转型:强制转换
  4. 方便方法调用,减少重复代码
  • 向上转型,这让代码更灵活(比如用父类作为方法参数,兼容所有子类)
  • 向下转型为了突破父类引用的限制,访问子类特有的功能

static

1
2
3
4
5
6
7
8
9
10
11
public  class Student(){
    public static int age;
    public string name;  
    public void run(){
        
    }
    public static void go(){
        
    }
    
}
  • 静态方法和非静态方法

    • 静态

      1
      2
      3
      Student.go();
      或者
      go();
    • 非静态

      1
      2
      Student s1=new Student;
      s1.run();
  • 看静态属性和非静态属性

    • 静态属性

      可以作为类变量调用

      1
      2
      System.out.println(Student.age);
      //name就不行
    • 属性

      1
      2
      3
      4
      Student s1=new Student;
      //这俩都能通过对象访问
      System.out.println(s1.age);
      System.out.println(s1.name);
  • 匿名代码块(啥也没,就俩大括号)

    1
    2
    {
    }
  • 静态代码块·(只执行一次)

    1
    2
    3
    static{
    
    }

最早输出的是: 静态代码块—匿名代码块—构造方法

第二次输出:匿名代码块—构造方法

抽象

  • abstract

    空着,先不写

    1
    2
    3
    4
    5
    6
    //abstract 抽象类:
    public abstract class Action {
        //约束~有人帮我们实现~
        //abstract ,抽象方法,只有方法名字,没有方法的实现!
        public abstract void doSomething();
    }

    继承抽象类 需要重写抽象方法

  • 总结:

    1. 不能new这个抽象类,只能靠子类去实现它:约束!(强制重写)
    2. 抽象类中可以写普通的方法
    3. 抽象方法必须在抽象类中

用于处理 一组具有共性但实现不同的事物,减少代码量(比如动物的叫声)

(针对用途)对比重写和抽象:

  • 重写:是实现抽象约束的核心手段,但是普通方法是“可选性”重写
  • 抽象:抽象类的抽象方法强制要求必须重写

接口

image-20251025193727309

​ 类 抽象类 接口

  • 接口:只有规范!自己无法写方法~专业的约束!约束和实现分离:面向接口编程

    接口的本质是契约(就像我们人间的法律一样。制定好后大家都遵守)

  • 多用接口,少用重写:

    原因:接口可以多继承,重写单继承(excends)

  • interface定义关键字

    1
    2
    3
    4
    5
    6
    7
    8
    //interface 定义的关键字, 接口都需要有实现类
    public interface UserService {
        //接口中的所有定义其实都是抽象的 public abstract(因为默认,所以隐藏了)
        void add(String name);
        void delete(String name);
        void update(String name);
        void query(String name);
    }
    1
    2
    3
    public interface TimeService {
    
    }
  • 接口要有实现类 implements(关键词)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    package com.oop.demo09;
    
    // 抽象类: extends~
    // 类 可以实现接口 implements 接口
    // 实现了接口的类,就需要重写接口中的方法~
    
    // 多继承~利用接口实现多继承~
    public class UserServiceImpl implements UserService, TimeService {
        @Override
        public void add(String name) {
        }
        @Override
        public void delete(String name) {
        }
        @Override
        public void update(String name) {
        }
        @Override
        public void query(String name) {
        }
        @Override
        public void timer() {
        }
    }

作用:

  1. 约束
  2. 定义一些方法,让不同的人实现 10——-1
  3. public abstract ()
  4. public static final (常量)
  5. 接口不能被实例化,接口中没有构造方法
  6. implements可以实现多个接日
  7. 必须要重写接口中的方法~

内部类(选)

  • 成员内部类

    image-20251025201724763

    而且,可以通过内部类来获得外部类的私有属性(private)

    但是,如果在内部类上加static,就访问不了私有属性

    因为:先实例化static内部类,才有外部类实例化,static内部类直接运行调用不到私有属性

  • 两个类可以在一个文件里面(不是互相包含的)

    image-20251025202950608

    一个文件只能有一个public class

  • 局部内部类

    方法里 写类

    image-20251025203107344


java入门
http://example.com/2025/10/28/java入门/
作者
Piggy Sprint
发布于
2025年10月28日
许可协议