Skip to content

day08.面向对象

java
课前回顾:
 1.封装:将细节隐藏起来(不让外界直接使用),对外提供公共的接口(让外界通过这个接口间接使用封装起来的细节)
 2.代表性关键字:private
   a.概述:私有权限
   b.作用范围:只能在当前类中使用
   c.使用:修饰成员变量,方法
 3.公共的接口:
   getxxx:获取属性值
   setxxx:为属性赋值
 4.this关键字:
   a.概述:代表的是当前对象,哪个对象调用的this所在的方法,this就代表哪个对象
   b.作用:区分重名的成员变量和局部变量 -> this后面一定是成员的
   c.注意:当成员变量和局部变量重名时,访问遵循"就近原则"
 5.无参构造:
   a.格式:
     public 类名(){}
   b.作用:new对象使用
   c.注意:每个类都有一个无参构造,不写默认也有
 6.有参构造:
   a.格式:
     public 类名(形参){
         为属性赋值
     }
   b.作用:
     new对象,为属性赋值
   c.注意:如果手写了有参构造,jvm将不再提供无参构造,所以我们需要都写上
 7.javabean
   a.概述:书写类的一种规范
   b.包含:
     public的类,非抽象的类
     属性私有
     get/set方法
     无参构造/有参构造

   c.作用:
     封装数据

  8.static关键字:
    a.概述:静态关键字
    b.使用:修饰成员变量,方法
    c.调用:类名直接调用
    d.特点:
      静态成员属于类成员,会随着类的加载而加载
      静态成员优先于对象存在
      凡是根据static所在的类创建出来的对象,都可以共享这个静态成员
    e.成员访问特点:
      不管在不在同一个类中,访问静态成员,能直接调用就直接调用,不能直接调用就类名调用
      不管在不在用一个类中,访问非静态成员,能直接调用就直接调用,不能直接调用就对象调用
    f.使用场景:
      抽取工具类

    g.工具类:
      构造私有化,成员都是静态的

今日重点:
  1.会使用可变参数
  2.会手撕冒泡排序,二分查找
  3.会往数组中存对象,会遍历

第一章.可变参数

java
1.需求:定义一个方法,实现若干个整数相加

2.分析需求:
  参数:类型确定了,但是个数不确定

1 介绍和基本使用

java
1.格式:
  数据类型...变量名

2.本质:可变参数本质上是数组

3.注意:
  参数位置只能有一个可变参数,而且要在参数列表最后
1742605938045
java
public class Demo01Var {
    public static void main(String[] args) {
        method(1,2,3,2,3,4,53,4,5);

        method02(1,2,3,4,5);
    }
    public static void method(int...arr){
        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum+=arr[i];
        }
        System.out.println("sum = " + sum);
    }

    public static void method02(int a,int...arr){

    }
}

2 可变参数

JDK1.5之后,如果我们定义一个方法时,此时某个形参的类型可以确定,但是形参的个数不确定,那么我们可以使用可变参数。

格式:

【修饰符】 返回值类型 方法名(【非可变参数部分的形参列表,】参数类型... 形参名){  }

要求:

(1)一个方法最多只能有一个可变参数

(2)如果一个方法包含可变参数,那么可变参数必须是形参列表的最后一个

(3)其实这个书写“≈”

【修饰符】 返回值类型 方法名(【非可变参数部分的形参列表,】参数类型[] 形参名){  }

只是后面这种定义,在调用时必须传递数组,而前者更灵活,既可以传递数组,又可以直接传递数组的元素,这样更灵活了。

示例一: 求 n 个整数的和

java
自己练习

示例二:字符串拼接

需求一:返回 n 个字符串拼接结果,如果没有传入字符串,那么返回空字符串""

java
public class Demo02Var {
    public static void main(String[] args) {
        String result = concat("唐老鸭", "光头强", "灰太狼", "哆啦A梦", "迪迦");
        System.out.println("result = " + result);
    }

    public static String concat(String...arr){
        String str = "";
        for (int i = 0; i < arr.length; i++) {
            str+=arr[i];
        }

        return str;
    }
}

需求二:n 个字符串进行拼接,每一个字符串之间使用某字符进行分隔,如果没有传入字符串,那么返回空字符串""

java
concat("-","柳岩","金莲","王婆","三上","松下") -> 柳岩-金莲-王婆-三上-松下
java
public class Demo03Var {
    public static void main(String[] args) {
        String result = concat("-", "唐老鸭", "光头强", "灰太狼", "哆啦A梦", "迪迦");
        System.out.println(result);
    }

    private static String concat(String s, String... arr) {
        String str = "";
        for (int i = 0; i < arr.length; i++) {
            if (i == arr.length - 1) {
                str += arr[i];
            } else {
                str += arr[i] + s;
            }
        }
        return str;
    }
}

第二章.递归

从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,讲的啥呢?

从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,讲的啥呢?

​ 从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,讲的啥呢?...

java
1.概述:方法内部自己调用自己
2.分类:
  a.直接递归: 方法内部自己调用自己
  b.间接递归:
    方法之间互相调用

3.注意:
  a.递归必须要有出口,否则会出现"栈内存溢出"
  b.即使有出口,也不要递归太多次,否则也会出现"栈内存溢出"
java
public class Demo01DiGui {
    public static void main(String[] args) {
        method();
    }

    public static void method() {
        method();//没有出口,就会出现栈内存溢出现象
    }
}

3.1 递归

  • 递归:指在当前方法内调用自己的这种现象。
  • 递归的分类:
    • 递归分为两种,直接递归和间接递归。
    • 直接递归称为方法自身调用自己。
    • 间接递归可以 A 方法调用 B 方法,B 方法调用 C 方法,C 方法调用 A 方法。
  • 注意事项
    • 递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出(因为会不断的压栈)。
    • 在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。

示例一:需求:利用递归输出 3 到 1

java
public class Demo02DiGui {
    public static void main(String[] args) {
        method(3);
    }

    public static void method(int n) {
        if (n==1){
            System.out.println(n);
            return;//结束方法
        }
        System.out.println(n);
        n--;
        method(n);
    }
}
1742608064735

示例二:求 n!

java
需求:求3的阶乘
    3*2*1

分析:3的阶乘相当于
    3*2的阶乘

    假设定义一个方法method(3)代表的是阶乘方法

    3的阶乘就相当于 -> 3*method(2)

规律: n的阶乘 -> n*method(n-1)
java
public class Demo03DiGui {
    public static void main(String[] args) {
        int result = method(3);
        System.out.println("result = " + result);
    }

    private static int method(int n) {
        if (n==1){
            return 1;
        }
        return n*method(n-1);
    }
}
1742609965609

示例三:计算斐波那契数列(Fibonacci)的第 n 个值

java
不死神兔
故事得从西元1202年说起,话说有一位意大利青年,名叫斐波那契。
在他的一部著作中提出了一个有趣的问题:假设一对刚出生的小兔一个月后就能长成大兔,再过一个月就能生下一对小兔,并且此后每个月都生一对小兔,一年内没有发生死亡
问:一对刚出生的兔子,一年内繁殖成多少对兔子?

规律:一个数等于前两个数之和,比如: 1 1 2 3 5 8 13 21 34 55....

1742610529669
java
1.假设定义一个方法,代表生兔子,参数为月份 method(n)

  method(1)        1
  method(2)        1
  method(3)        2 -> method(1)+method(2)
  method(4)        3 -> method(2)+method(3)
  method(5)        5 -> method(3)+method(4)

2.结论:
  n个月 -> method(n-1)+method(n-2)
java
public class Demo04DiGui {
    public static void main(String[] args) {
        int result = method(12);
        System.out.println("result = " + result);
    }
    public static int method(int n){
        if (n==1||n==2){
            return 1;
        }
        return method(n-1)+method(n-2);
    }
}

第三章.数组操作

1.数组翻转

java
1.概述:数组中对称索引位置上的元素互换
1742611508879
java
public class Demo01Rerverse {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6,7,8,9,10};
        for (int min = 0,max = arr.length-1;min<max;min++,max--){
            int temp = arr[min];
            arr[min] = arr[max];
            arr[max] = temp;
        }

        System.out.println(Arrays.toString(arr));
    }
}

2.冒泡排序

数组的排序,是将数组中的元素按照大小进行排序,默认都是以升序的形式进行排序,数组排序的方法很多,我们讲解的是数组的冒泡排序。

排序,都要进行数组 元素大小的比较,再进行位置的交换。冒泡排序法是采用数组中相邻元素进行比较换位。

2.1 冒泡排序图解

1742613490096

2.2 代码实现

java
public class Demo02MaoPao {
    public static void main(String[] args) {
        int[] arr = {5,4,3,2,1};
        /*
           当i到4的时候,i<5?true ->进循环 -> if(arr[4]>arr[4+1])
           此数组没有5索引,所以越界了

           解决:让arr.length减去1


           第一圈:比较了4次
         */
        /*for (int i = 0; i < arr.length-1-0; i++) {
            if (arr[i]>arr[i+1]){
                int temp = arr[i];
                arr[i] = arr[i+1];
                arr[i+1] = temp;
            }
        }

        System.out.println(Arrays.toString(arr));*/

        /*
           第二圈:比较了3次
         */
       /* for (int i = 0; i < arr.length-1-1; i++) {
            if (arr[i]>arr[i+1]){
                int temp = arr[i];
                arr[i] = arr[i+1];
                arr[i+1] = temp;
            }
        }

        System.out.println(Arrays.toString(arr));*/

         /*
           第三圈:比较了2次
         */
        /*for (int i = 0; i < arr.length-1-2; i++) {
            if (arr[i]>arr[i+1]){
                int temp = arr[i];
                arr[i] = arr[i+1];
                arr[i+1] = temp;
            }
        }

        System.out.println(Arrays.toString(arr));*/

         /*
           第四圈:比较了1次
         */
        /*for (int i = 0; i < arr.length-1-3; i++) {
            if (arr[i]>arr[i+1]){
                int temp = arr[i];
                arr[i] = arr[i+1];
                arr[i+1] = temp;
            }
        }

        System.out.println(Arrays.toString(arr));*/

        /*
           外层代表几圈
           内层代表比较次数
         */
        for (int j = 0; j < arr.length-1; j++) {
            for (int i = 0; i < arr.length-1-j; i++) {
                if (arr[i]>arr[i+1]){
                    int temp = arr[i];
                    arr[i] = arr[i+1];
                    arr[i+1] = temp;
                }
            }
        }

        System.out.println(Arrays.toString(arr));
    }
}

3.二分查找

java
1.问题:
  之前我们从数组中查询元素,我们需要遍历数组,然后元素和我们想要找的数据挨个比较,这样查询起来就会很慢
  [11,22,33,44,55,66,77,88]

2.二分查找:
  a.作用:提高查询效率
  b.前提:数组必须是有序的 -> 一般都是升序

3.中心思想:
  先找一个数组的中间索引,然后用我们的数据和中间索引对应的元素比较,如果查不到,下次查找干掉数组的一半,跟另外一半的中间索引比较....
1742623997494
java
public class Demo03BinarySearch {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6,7,8,9,10};
        int index = binarySearch(arr);
        System.out.println("index = " + index);
    }

    public static int binarySearch(int[] arr) {
        //定义min和max以及mid
        int min = 0;
        int max = arr.length-1;
        int mid = 0;
        int key = 10;
        while(min<=max){
            mid = (min+max)/2;
            if (key>arr[mid]){
                min = mid+1;
            } else if (key<arr[mid]){
                max = mid-1;
            }else{
                return mid;
            }
        }
        return -1;
    }
}

4.对象数组

java
需求:定义一个数组,存储3个Person对象,遍历数组,将3个对象中的属性值获取出来
java
public class Person {
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
java
public class Demo04ObjectArray {
    public static void main(String[] args) {
        /*
          1.存储int型数据 -> int[]
          2.存储double型数据 -> double[]
          3.存储String字符串数据 -> String[]
          4.存储Person对象数据 -> Person[]

          Person p = new Person()
          等号左边的Person是数据类型
          p:对象名
          new Person():创建对象,是p的具体值
         */

        Person[] arr = new Person[3];
        Person p1 = new Person("张三", 10);
        Person p2 = new Person("李四", 11);
        Person p3 = new Person("王五", 12);

        //将三个Person对象存储到数组中
        arr[0] = p1;
        arr[1] = p2;
        arr[2] = p3;

        //遍历
        for (int i = 0; i < arr.length; i++) {
            /*
               i = 0,arr[0]就是p1 -> 将p1的地址值给了p,此时p就是p1
               i = 1,arr[1]就是p2 -> 将p2的地址值给了p,此时p就是p2
               i = 2,arr[2]就是p3 -> 将p3的地址值给了p,此时p就是p3
             */
            //Person p = arr[i];
            //System.out.println(p.getName()+"..."+p.getAge());
            System.out.println(arr[i].getName()+"..."+arr[i].getAge());

        }
    }
}
1742625939737

练习 1

(1)定义学生类 Student

​ 声明姓名和成绩成员变量

(2)测试类 ObjectArrayTest 的 main 中创建一个可以装 3 个学生对象的数组,并且按照学生成绩排序,显示学生信息

java
public class Student {
    private String name;
    private int score;

    public Student() {
    }

    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }
}
java
public class Demo05ObjectArray {
    public static void main(String[] args) {
        //创建Student数组
        Student[] arr = new Student[3];
        Student s1 = new Student("张三", 100);
        Student s2 = new Student("李四", 60);
        Student s3 = new Student("王五", 80);

        arr[0] = s1;
        arr[1] = s2;
        arr[2] = s3;

        for (int j = 0; j < arr.length - 1; j++) {
            for (int i = 0; i < arr.length - 1 - j; i++) {
                if (arr[i].getScore() > arr[i + 1].getScore()) {
                    Student temp = arr[i];
                    arr[i] = arr[i + 1];
                    arr[i + 1] = temp;
                }
            }
        }


        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i].getName() + "..." + arr[i].getScore());
        }

    }
}

第四章.方法参数

1.基本数据类型做方法参数传递

java
基本类型做方法参数传递,传递的是变量的值,不是变量本身
java
public class Test01 {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        /*
           参数为基本类型,传递的是变量代表的值
           不是变量本身
         */
        method(a,b);
        System.out.println(a);//10
        System.out.println(b);//20
    }
    public static void method(int a,int b){
        a+=10;
        b+=20;
        System.out.println(a);//20
        System.out.println(b);//40
    }
}

2.引用数据类型做方法参数传递

java
引用类型做方法参数传递,传递的地址值
java
public class Test02 {
    public static void main(String[] args) {
        int[] arr = {10,20};
        method(arr);
        System.out.println(arr[0]);//20
        System.out.println(arr[1]);//40
    }
    public static void method(int[] arr){
        arr[0]+=10;
        arr[1]+=20;
        System.out.println(arr[0]);//20
        System.out.println(arr[1]);//40
    }
}
1742630054763

第五章.命令行参数(了解)

通过命令行给 main 方法的形参传递的实参称为命令行参数

1616663442452

java
public class TestCommandParam{
	//形参:String[] args
	public static void main(String[] args){
		for(int i=0; i<args.length; i++){
			System.out.println("第" + (i+1) + "个参数的值是:" + args[i]);
		}
	}
}

运行命令:

command
java TestCommandParam
command
java TestCommandParam 1 2 3
command
java TestCommandParam hello atguigu
1720957138491

第六章.快速生成方法小技巧

1.先调用,再生成

java
先调用,按alt+回车 ->选择创建方法
1742631305966

2.快速将一段代码放到一个方法中

java
1.选中要抽取的代码
2.按ctrl+alt+m