• Java类与面向对象(创建对象 成员方法 形参实参 递归 重载 可变参数 作用域 构造方法 this)



    image-20221107180140153

    张老太养了两只猫猫:一只名字叫小白,今年3岁,白色。还有一只叫小花,今年100岁,花色。请编写一个程序,当用户输入小猫的名字时,就显示该猫的名字,年龄,颜色。如果用户输入的小猫名错误,则显示张老太没有这只猫猫。

    public class Test {
        public static void main(String[] args) {
            // 单独变量来解决=>不利于数据的管理
            // 第1只猫信息
            String cat1Name = "小白";
            int cat1Age = 3;
            String cat1Color = "白色";
            // 第2只猫信息
            String cat2Name = "小花";
            int cat2Age = 100;
            String cat2Color = "花色";
    
            // 用String数组呢?
            // 缺点 1数据类型体现不出来 2只能通过下标获取信息 3不能体现猫的行为
            String[] cat1 = {"小白", "13", "白色"};
            String[] cat2 = {"小花", "100", "花色"};
            // 现有技术解决的缺点分析
            // 1不利于数据的管理
            // 2效率低
            // --->>>>>>>>>>> 引出我们的新知识点类与对象
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    面向对象快速入门

    public class Test {
        public static void main(String[] args) {
            // cat1对象
            Cat cat1 = new Cat();
            cat1.name = "小白";
            cat1.age = 3;
            cat1.color = "白色";
            // 怎么使用 访问对象属性
            System.out.println("第一支猫信息: " + cat1.name + " " + cat1.age + " " + cat1.color);
        }
    }
    
    // 定义一个猫类Cat ->自定义的数据类型
    class Cat {
        // 属性
        String name; // 名字
        int age; // 年 龄
        String color; // 颜色
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    对象在内存中存在形式

    image-20221031162029036

    类与对象

    基本介绍
    1.从概念或叫法上看:成员变量=属性= field(字段) (即成员变量是用来表示属性的,授课中,统一叫属性)
    案例演示: Car(name,price,color)

    2.属性是类的一个组成部分,一般是基本数据类型,也可是引用类型(对象,数组)。 比如我们前面定义猫类的int age就是属性

    class Car {
        // 属性
        String name; // 属性 成员变量 字段 field
        int price;
        String color;
        String[] master;// 属性可以是基本数据类型,也可以是引用类型(对象,数组)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    属性注意事项

    1)属性的定义语法同变量,示例:访问修饰符属性类型属性名;
    这里简单的介绍访问修饰符:控制属性的访问范围
    有四种访问修饰符public, protected,默认,private ,后面详细介绍

    2)属性的定义类型可以为任意类型,包含基本类型或引用类型

    3)属性如果不赋值,有默认值,规则和数组一致。

    类与对象内存分配机制

    image-20221031165505874

    public class Test {
        public static void main(String[] args) {
            Person p1 = new Person();
            p1.age = 10;
            p1.name = "小明";
            Person p2 = p1;
            System.out.println(p2.age);
        }
    }
    
    class Person {
        // 属性
        String name; // 属性 成员变量 字段 field
        int age;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    类和对象的内存分配机制

    Java内存的结构分析

    1 栈: 一般存放基本数据类型(局部变量)

    2 堆:存放对象(Cat cat ,数组等)

    3 方法区:常量池(常量,比如字符串), 类加载信息

    4 示意图[Cat (name, age, price)]

    Java创建对象的流程简单分析

    image-20221031170003073

    public class Test {
        public static void main(String[] args) {
            // 我们看看下面一段代码,会输出什么信息:
            Person a = new Person();
            a.age = 10;
            a.name = "小明";
            Person b;
            b = a;
            System.out.println(b.name);
            b.age = 200;
            b = null;
            System.out.println(a.age);
            System.out.println(b.age);
        }
    }
    
    class Person {
        // 属性
        String name; // 属性 成员变量 字段 field
        int age;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    小明
    200
    b.age抛出异常

    image-20221031170515959

    成员方法快速入门

    在某些情况下,我们要需要定义成员方法(简称方法)。比如人类:除了有一些属性外(年龄,姓名…),我们人类还有一些行为比如:可以说话、跑步…通过学习,还可以做算术题。这时就要用成员方法才能完成。现在要求对Person类完善。

    成员方法快速入门
    1)添加speak成员方法,输出我是一只好人
    2)添加cal01成员方法 , 可以计算从 1 + . . . + 1000 1 +...+ 1000 1+...+1000的结果
    3)添加cal02成员方法,该方法可以接收一个数n,计算从 1 + . . . + n 1+...+n 1+...+n的结果
    4)添加getSum成员方法,可以计算两个数的和

    public class Test {
        public static void main(String[] args) {
            // 我们看看下面一段代码,会输出什么信息:
            Person a = new Person();
            a.age = 10;
            a.name = "小明";
            a.speak();
        }
    }
    
    class Person {
        // 属性
        String name; // 属性 成员变量 字段 field
        int age;
    
        public void speak() {
            System.out.println("我是个好人");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    方法调用机制

    image-20221031173818347

    为什么需要成员方法

    看一个需求:

    int [][] map ={{0,0,1},{1,1,1},{1,1,3}};
    
    • 1

    请遍历一个数组,输出数组的各个元素值。

    解决思路1,传统的方法,就是使用单个for循环,将数组输出,大家看看问题是什么?
    解决思路2:定义一个类MyTools 然后写一个成员方法,调用方法实现,看看效果又如何。

    成员方法的好处
    提高代码的复用性
    可以将实现的细节封装起来,然后供其他用户来调用即可。

    返回数据类型

    1.一个方法最多有一个返回值[思考,如何返回多个结果? ] [返回数组]
    2.返回类型可以为任意类型,包含基本类型或引用类型(数组,对象)
    3.如果方法要求有返回数据类型,则方法体中最后的执行语句必须为return值;而且要求返回值类型必须和return的值类型一致或兼容
    4.如果方法是void,则方法体中可以没有return语句,或者只写return ;

    方法名

    遵循驼峰命名法,最好见名知义,表达出该功能的意思即可,比如得到两个数的和getSum, 开发中按照规范

    形参列表

    1.一个方法可以有0个参数, 也可以有多个参数,中间用逗号隔开
    2.参数类型可以为任意类型, 包含基本类型或引用类型
    3.调用带参数的方法时,一定对应着参数列表传入相同类型或兼容类型的参数
    4.方法定义时的参数称为形式参数, 简称形参;方法调用时的参数称为实际参数,简称实参,实参和形参的类型要一致或兼容、 个数、顺序必须一致! [演示]

    方法体

    里面写完成功能的具体的语句,可以为输入、输出、变量、运算、分支、循环、方法调用,但里面不能再定义方法!即:方法不能嵌套定义。

    方法调用细节说明
    • 同一个类中的方法调用:直接调用即可。
    • 跨类中的方法A类调用B类方法:需要通过对象名调用。比如对象名.方法名(参数);
    • 特别说明一下:跨类的方法调用和方法的访问修饰符相关,先暂时这么提一下 ,后面我们讲到访问修饰符时,还要再细说。

    成员方法传参机制

    基本数据类型传参机制

    方法的传参机制对我们今后的编程非常重要,一定要搞的清清楚楚明明自白。我们通过案例来学习

    public class Test {
        public static void main(String[] args) {
            int a = 10;
            int b = 20;
            AA aa = new AA();
            aa.swap(a, b);
            System.out.println("\n3 a和b交换后的值\na=" + a + "\tb=" + b);
        }
    }
    
    class AA {
        public void swap(int a, int b) {
            System.out.println(" \n1 a和b交换前的值\na=" + a + "\tb=" + b);
            // 完成了a和b的交换
            int tmp = a;
            a = b;
            b = tmp;
            System.out.println("\n2 a和b交换后的值\na=" + a + "\tb=" + b);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    可是为什么实际上的传入方法的a,b没有改变呢?

    基本数据类型,传递的是值(值拷贝) ,形参的任何改变不影响实参!

    引用数据类型的传参机制

    B类中编写一个方法test100,可以接收一个数组,在方法中修改该数组,看看原来的数组是否变化?
    B类中编写一个方法test200,可以接收一个Person(age,sal)对象, 在方法中修改该对象属性,看看原来的对象是否变化?

    public class Test {
        public static void main(String[] args) {
            B b = new B();
            int[] arr = {1, 2, 3};
            // B类中编写一个方法test100,可以接收一个数组,在方法中修改该数组,看看原来的数组是否变化? 
            b.test100(arr);
            System.out.println(arr[0]);
            // B类中编写一个方法test200,可以接收一个Person(age,sal)对象, 在方法中修改该对象属性,看看原来的对象是否变化?
    
        }
    }
    
    class B {
        public void test100(int[] arr) {
            arr[0] = 100;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    引用类型传递的是地址(传递也是值,但是值是地址) ,可以通过形参影响实参!

    public class Test {
        public static void main(String[] args) {
            Person p = new Person();
            p.name = "jack";
            p.age = 12;
            B b = new B();
            b.test200(p);
            System.out.println("main的p.age=" + p.age);
    
        }
    }
    
    class Person {
        String name;
        int age;
    }
    
    class B {
        public void test200(Person p) {
            // p.age = 888;  // 情况1
            // p = null; //情况2
            p = new Person(); //情况3
            p.age = 999;
        }
    }
    
    • 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
    克隆对象

    编写一个方法copyPerson, 可以复制一个Person对象, 返回复制的对象。克隆对象,
    注意要求得到新对象和原来的对象是两个独立的对象,只是他们的属性相同

    public class Test {
        public static void main(String[] args) {
            Person p = new Person();
            p.name = "jack";
            p.age = 12;
            MyTools tools = new MyTools();
            Person p2 = tools.copyPerson(p);
            // 此时p2与p属性相同,地址不同
            System.out.println(p2.name + " is " + p2.age);
            // 可以通过输出对象的hashCode看看对象是否是同一个
            System.out.println("p的hashCode " + p.hashCode());
            System.out.println("p2的hashCode " + p2.hashCode());
    
        }
    }
    
    class Person {
        String name;
        int age;
    }
    
    class MyTools {
        public Person copyPerson(Person p) {
            Person p2 = new Person();
            p2.age = p.age;
            p2.name = p.name;
            return p2;
        }
    }
    
    • 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

    递归

    1.执行一个方法时,就创建一个新的受保护的独立空间(栈空间)
    2.方法的局部变量是独立的,不会相互影响,比如n变量
    3.如果方法中使用的是引用类型变量(比如数组),就会共享该引用类型的数据.
    4.递归必须向退出递归的条件逼近,否则就是无限递归,出现StackOverflowError,死龟了:)
    5.当一个方法执行完毕,或者遇到return, 就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕。

    image-20221106120441075

    public class Test {
        public static void main(String[] args) {
            T t1=new T();
            t1.test(4);
        }
    }
    
    class T {
        public void test(int n) {
            if (n > 2) {
                test(n - 1);
            }
            System.out.println("n=" + n);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    1 斐波那契数列

    1.请使用递归的方式求出斐波那契数列 1,1,2,3,5,8,13…的第n个值是多少?

    public class Test {
        public static void main(String[] args) {
            T t1 = new T();
            System.out.println(t1.fibonacci(50));
        }
    }
    
    class T {
        public long fibonacci(int n) {
            if (n > 2) {
                return fibonacci(n - 1) + fibonacci(n - 2);
            } else if (n == 1 || n == 2) {
                return 1;
            }
            return -1;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    2 猴子吃桃子

    问题:有一堆桃子,猴子第一天吃了其中的一半,并再多吃了一个! 以后每天猴子都吃其中的一半,然后再多吃一个。当到第10天时,想再吃时(即还没吃)发现只有1个桃子了。问题:最初共多少个桃子?

    思路分析逆推

    day =10时有1个桃子
    day=9时有 ( d a y 10 + 1 ) ∗ 2 = 4 (day10+1)*2=4 (day10+1)2=4
    day=8时有 ( d a y 9 + 1 ) ∗ 2 = 10 (day9+1)*2=10 (day9+1)2=10

    public class Test {
        public static void main(String[] args) {
            T t1 = new T();
            System.out.println(t1.peach(1));
        }
    }
    
    class T {
        public int peach(int day) {
            if (day == 10) {
                return 1;
            } else if (day >= 1 && day < 10) {
                return 2 * (peach(day + 1) + 1);
            }
            return -1;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    3 老鼠走迷宫

    image-20221106195337140

    public class Test {
        public static void main(String[] args) {
            // 先创建迷宫, 用二维数组表示
            // 规定map数组的值代表的含义 0可以走,1是有障碍物
            int[][] map = new int[8][7];
            // 将最上面一行和最下面一行,全部置为1
            for (int i = 0; i < 7; i++) {
                map[0][i] = 1;
                map[7][i] = 1;
            }
            // 将最左边和最右边也置为1
            for (int i = 0; i < 7; i++) {
                map[i][0] = 1;
                map[i][6] = 1;
            }
            // 还有隔板置为1
            map[3][1] = 1;
            map[3][2] = 1;
            // 输出当前的地图
            System.out.println("===========当前地图情况==============");
            for (int i = 0; i < map.length; i++) {
                for (int j = 0; j < map[i].length; j++) {
                    System.out.print(map[i][j] + "\t");
                }
                System.out.println();
            }
            // 使用findWay给老鼠找路
            T t1 = new T();
            t1.findWay(map, 1, 1);
            // 输出找到的路
            System.out.println("===========找完了路==============");
            for (int i = 0; i < map.length; i++) {
                for (int j = 0; j < map[i].length; j++) {
                    System.out.print(map[i][j] + "\t");
                }
                System.out.println();
            }
    
        }
    }
    
    class T {
        // 使用递归回溯的方法找路
        // findWay就是专门来找迷宫的路径
        // 找到了就true,没找到就是false
        // map就是二维数组,表示迷宫
        // i,j就是老鼠的位置,初始化的位置为(1,1)
        // map数组里各个值的含义
        // 0表示可以走. 1表示障碍物, 2表示可以走,3表示走过但是走不通
        // 当map[6][5]=2就说明找到通路,就可以结束,否则就继续找
        // 先确实老鼠找路策略,  下-右-上-左
        public boolean findWay(int[][] map, int i, int j) {
            if (map[6][5] == 2) {// 说明已经找到了
                return true;
            } else {
                if (map[i][j] == 0) {// 0 可以走
                    // 我们假设可以走通
                    map[i][j] = 2;
                    // 使用 下-右-上-左 找路策略试试
                    if (findWay(map, i + 1, j)) {// 下
                        return true;
                    } else if (findWay(map, i, j + 1)) {// right
                        return true;
                    } else if (findWay(map, i - 1, j)) {// upper
                        return true;
                    } else if (findWay(map, i, j - 1)) {// left
                        return true;
                    } else {
                        map[i][j] = 3;
                    }
                } else {// map[i][j]=1,2,3
                    return false;
                }
            }
            return false;
        }
    }
    
    • 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
    • 74
    • 75
    • 76
    • 77
    4 汉诺塔

    汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一-次只能移动一个圆盘。

    假如每秒钟移动一次,共需多长时间呢?移完这些金片需要5845.54亿年以上,太阳系的预期寿命据说也就是数百亿年。真的过了5845.54亿年,地球上的一切生命,连同梵塔、庙宇等,都早已经灰飞烟灭

    public class Test {
        public static void main(String[] args) {
            Tower t = new Tower();
            t.move(2, 'A', 'B', 'C');
        }
    }
    
    class Tower {
        // num表示要移动的个数,a b c分别代表A塔 B塔 C塔
        public void move(int num, char a, char b, char c) {
    		// 如果只有一个盘
            if (num == 1) {
                System.out.println(a + "->" + c);
            } else {
                // 如果有多个盘,可以简化成最下面和上面的所有
                // 1 移动上面所有的盘到b,借助c
                move(num - 1, a, c, b);
                // 2 最下面的盘,到c
                System.out.println(a + "->" + c);
                // 3 再把b的所有盘移动到c,借助a
                move(num - 1, b, a, c);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    5 八皇后问题

    八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯.贝瑟尔于1848年提出:在8x8格的国际象棋上摆放八个皇后,使其不能互相攻击,即:任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

    1)第一个皇后先放第一行第一 列
    2)第二个皇后放在第二行第一列、 然后判断是否OK,如果不OK, 继续放在第二列、第三列、依次把所有列都放完,找到一个合适
    3)继续第三个皇后,还是第一-列、第二列…直到第8个皇后也能放在一个不冲突的位置,算是找到了一个正确解
    4)当得到一个正确解时,在栈回退到,上一个栈时,就会开始回溯,即将第一个皇后,放到第一列的所有正确解, 全部得到.
    5)然后回头继续第一个皇后放第二列,后面继续循环执行1,2,3,4的步骤

    说明:理论上应该创建一个二维数组来表示棋盘,但是实际上可以通过算法,用一个一维数组即可解决问题。arr[8] = {0, 4, 7, 5, 2, 6, 1,3} //对应arr下标表示第几行,即第几个皇后,arr[i] = val, val表示第 i + 1 i+1 i+1个皇后,放在第 i + 1 i+1 i+1行的第 v a l + 1 val+1 val+1

    . 😪不会写 放弃

    重载

    java中允许同一个类中,多个同名方法的存在,但要求形参列表不一致!
    比如: System.out.println(); out是PrintStream类型

    重载的好处
    1)减轻了起名的麻烦
    2)减轻了记名的麻烦

    class MyCalculator {
        // 下面四个calculate方法构成了重载
        public int calculate(int n1, int n2) {
            return n1 + n2;
        }
        public double calculate(int n1, double n2) {
            return n1 + n2;
        }
        public double calculate(double n1, int n2) {
            return n1 + n2;
        }
        public int calculate(int n1, int n2, int n3) {
            return n1 + n2 + n3;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    重载使用细节

    1)方法名:必须相同
    2)形参列表:必须不同(形参类型或个数或顺序,至少有一样不同,参数名无要求)
    3)返回类型:无要求

    1.编写程序,类Methods中定义三个重载方法并调用。方法名为m。三个方法分别接收一个int参数、两个int参数、一个字符串参数。分别执行平方运算并输出结果,相乘并输出结果,输出字符串信息。在主类的main ()方法中分别用参数区别调用三个方法。

    public class Test {
        public static void main(String[] args) {
            Methods method = new Methods();
            method.m(3);
            method.m(3, 1);
            method.m("妈妈我要回家");
        }
    }
    
    class Methods {
        // 下面四个calculate方法构成了重载
        public void m(int n) {
            System.out.println(n * n);
        }
    
        public void m(int n1, int n2) {
            System.out.println(n1 * n2);
            ;
        }
    
        public void m(String s) {
            System.out.println(s);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    2.在Methods类, 定义三个重载方法max(),第一个方法,返回两个int值中的最大值,第二个方法,返回两个double值中的最大值,第三个方法,返回三个double值中的最大值,并分别调用三个方法。

    略略略…

    可变参数

    java允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法。

    基本语法

    访问修饰符 返回类型 方法名(数据类型... 形参名) {
    }
    
    • 1
    • 2

    看一个案例类Methods, 方法sum [可以计算 2个数的和,3个数的和,4, 5, …]

    public class Test {
        public static void main(String[] args) {
            Methods method = new Methods();
            System.out.println(method.sum(3, 1, 79));
        }
    }
    
    class Methods {
        // 1. int...表示接受的是可变参数,类型是int ,即可以接收多个int(0-多)
        // 2. 使用可变参数时,可以当做数组来使用, 即nums可以当做数组
        public int sum(int... nums) {
            int res = 0;
            for (int i = 0; i < nums.length; i++) {
                res += nums[i];
            }
            return res;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    注意事项和使用细节

    1)可变参数的实参可以为0个或任意多个。
    2)可变参数的实参可以为数组。
    3)可变参数的本质就是数组.
    4)可变参数可以和普通类型的参数一起放在形参列表, 但必须保证可变参数在最后
    5)一个形参列表中只能出现一个可变参数

    有三个方法,分别实现返回姓名和两门课成绩(总分),返回姓名和三门课成绩(总分),返回姓名和五门课成绩(总分)。封装成一个可变参数的方法

    不想做

    String name, double… scores

    作用域

    1 在java编程中,主要的变量就是属性(成员变量)和局部变量。

    2 我们说的局部变量一-般是指在成员方法中定义的变量。

    3 java中作用域的分类
    全局变量:也就是属性,作用域为整个类体Cat类: cry eat等方法使用属性[举例]
    局部变量:也就是除了属性之外的其他变量,作用域为定义它的代码块中!

    4 全局变量可以不赋值,直接使用,因为有默认值,局部变量(比如方法里的变量)必须赋值后,才能使用,因为没有默认值。

    注意事项和细节使用

    1.属性和局部变量可以重名,访问时遵循就近原则。

    2.在同一个作用域中,比如在同一个成员方法中,两个局部变量,不能重名。[举例]

    3.属性生命周期较长,伴随着对象的创建而创建,伴随着对象的死亡而死亡。局部变量,生命周期较短,伴随着它的代码块的执行而创建,伴随着代码块的结束而死亡。即在一次方法调用过程中。

    4.作用域范围不同
    全局变量/属性:可以被本类使用,或其他类使用(通过对象调用)
    局部变量:只能在本类中对应的方法中使用

    5.修饰符不同
    全局变量/属性可以加修饰符
    局部变量不可以加修饰符

    构造方法/构造器

    看一个需求
    我们来看一个需求:前面我们在创建人类的对象时,是先把一个对象创建好后, 再给他的年龄和姓名属性赋值,如果现在我要求,在创建人类的对象时,就直接指定这个对象的年龄和姓名,该怎么做? 这时就可以使用构造器。

    基本语法

    [修饰符] 方法名 (形参列表) {
    方法体;
    }
    
    • 1
    • 2
    • 3

    1)构造器的修饰符可以默认
    2)构造器没有返回值
    3)方法名和类名字必须一样
    4)参数列表和成员方法一样的规则
    5)构造器的调用系统完成

    构造方法又叫构造器(constructor),是类的一种特殊的方法,它的主要作用是完成对新对象的初始化。它有几个特点:

    1)方法名和类名相同
    2)没有返回值
    3)在创建对象时,系统会自动的调用该类的构造器完成对对象的初始化。

    public class Test {
        public static void main(String[] args) {
            Person p = new Person(998, "佩奇");
            System.out.println(p.name + " is " + p.age);
        }
    }
    
    class Person {
        int age;
        String name;
    
        public Person(int age, String name) {
            this.age = age;
            this.name = name;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    注意事项和使用细节

    1.一个类可以定义多个不同的构造器,即构造器重载
    比如:我们可以再给Person类定义一个构造器,用来创建对象的时候,只指定人名,不需要指定年龄
    2.构造器名和类名要相同
    3.构造器没有返回值
    4.构造器是完成对象的初始化,并不是创建对象
    5.在创建对象时,系统自动的调用该类的构造方法

    public class Test {
        public static void main(String[] args) {
            Person p = new Person(998, "佩奇");
            System.out.println(p.name + " is " + p.age);
        }
    }
    
    class Person {
        int age;
        String name;
    
        public Person(int age, String name) {
            this.age = age;
            this.name = name;
        }
        public Person(String name) {  //构造器重载
            this.name = name;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    6.如果程序员没有定义构造方法,系统会自动给类生成一个默认无参构造方法(也叫默认构造方法),比如Person (){}, 使用javap指令反编译看看
    7.一旦定义了自己的构造器,默认的构造器就覆盖了,就不能再使用默认的无参构造器,除非显式的定义一下,即: Person(){}

    image-20221107175534480

    1.加载Person类信息(Person.class) ,只会加载一次
    2.在堆中分配空间(地址)
    3.完成对象初始化
    3.1默认初始化age=0 name=null
    3.2显式初始化 age=90,name=nulI,
    3.3构造器的初始化age =20, name=小倩]
    4.在对象在堆中的地址返回给p(p是对象名,也可以理解成是对象的引用)

    this关键字

    java虚拟机会给每个对象分配this,代表当前对象。

    简单的说,哪个对象调用,this就代表哪个对象

    使用细节

    1. this关键字可以用来访问本类的属性、方法、构造器
    2. this用于区分当前类的属性和局部变量
    3. 访问成员方法的语法: this.方法名(参数列表);
    4. 访问构造器语法: this(参数列表); 注意只能在构造器中使用(即只能在构造器中访问另外一个构造器,必须放在方法第一条语句)
    5. this不能在类定义的外部使用,只能在类定义的方法中使用。

    定义Person类,里面有name、age属性,并提供compareTo比较方法,用于判断是否和另一一个人相等,提供测试类TestPerson用于测试,名字和年龄完全一样,就返回true, 否则返回false

    public class TestPerson {
        public static void main(String[] args) {
            Person p1 = new Person(998, "佩奇");
            Person p2 = new Person(998, "佩奇");
            System.out.println(p1.compareTo(p2));
        }
    }
    
    class Person {
        int age;
        String name;
    
        public Person(int age, String name) {
            this.age = age;
            this.name = name;
        }
    
        public boolean compareTo(Person p) {
            if (this.name.equals(p.name) && this.age == p.age) {
                return true;
            } else {
                return false;
            }
        }
    }
    
    • 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

    本章作业

    1.编写类A01, 定义方法max, 实现求某个double数组的最大值,并返回

    public class Test {
    
        public static double max(double[] arr) {
            double max = arr[0];
            for (int i = 0; i < arr.length; i++) {
                max = max > arr[i] ? max : arr[i];
            }
            return max;
        }
    
    
        public static void main(String args[]) {
            double[] array = {1.1, 2.6, 0.1, 9.9, 5, -2};
            System.out.println(max(array));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    2.编写类A02,定义方法find,实现查找某字符串数组中的元素查找,并返回索引,如果找不到,返回-1 .

    public class Test {
    
        public static int find(String target, String[] strs) {
            int index = -1;
            for (int i = 0; i < strs.length; i++) {
                if (target.equals(strs[i])) {
                    index = i;
                }
            }
            return index;
        }
    
    
        public static void main(String args[]) {
            String[] array = {"你好", "再见", "白山茶", "丘丘人", "派蒙", "应急食物"};
            System.out.println(find("丘丘人", array));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3.编写类Book,定义方法updatePrice, 实现更改某本书的价格,具体:如果价格>150,则更改为150,如果价格> 100,更改为100,否则不变

    if price>150:
    	price=150
    elif price>100:
        price=100     
    
    • 1
    • 2
    • 3
    • 4

    4.编写类A03,实现数组的复制功能copyArr,输入旧数组,返回一个新数组,元素和旧数组一样

    循环遍历复制就是,也不难
    
    • 1

    5.定义一个圆类Circle, 定义属性: 半径,提供显示圆周长功能的方法,提供显示圆面积的方法

    public class Test {
        public static void main(String args[]) {
            Circle c = new Circle();
            c.radius = 3.0;
            System.out.println(String.format("周长是%f, 面积是%f", c.circumference(), c.area()));
        }
    }
    
    class Circle {
        double radius;
    
        public double circumference() {
            return 2 * Math.PI * radius;
        }
    
        public double area() {
            return Math.PI * radius * radius;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    6.编程创建一个Cale计算类, 在其中定义2个变量表示两个操作数,定义四个方法实现求和、差、乘、商(要求除数为0的话,要提示)并创建两个对象,分别测试

    op1 op2
    def sum(op1, op2):
        pass
    
    • 1
    • 2
    • 3

    7.设计一个Dog类,有名字、颜色和年龄属性,定义输出方法show()显示其信息。并创建对象,进行测试、[提示 this.属性]

    show? 还可以骚点,用toString.
    
    • 1

    8.给定一个Java程序的代码如下所示,则编译运行后,输出结果是()

    public class Test {
        int count = 9;
    
        public void count1() {
            count = 10;
            System.out.println("count1=" + count);
        }
    
        public void count2() {
            System.out.println("count1=" + count++);
        }
    
        public static void main(String args[]) {
            new Test().count1();
            Test t1 = new Test();
            t1.count2();
            t1.count2();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    // new Test() 是匿名对象, 匿名对象使用后,就不能使用
    // new Test().count1() 创建好匿名对象后,就调用count1()
    运行结果
    count1=10
    count1=9
    count1=10
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    9.定义Music类,里面有音乐名name、 音乐时长times属性,并有播放play功能和返回本身属性信息的功能方法getlnfo.

    10.试写出以下代码的运行结果()

    image-20221107222314439

    i=101
    j=100
    101
    101
    
    • 1
    • 2
    • 3
    • 4

    11.在测试方法中,调用method方法,代码如下,编译正确,试写出method方法的定义形式,调用语句为: System.out.println(method(method(10.0,20.0),100);

    (double... )
    
    • 1

    12.创建一个Employee类,属性有(名字, 性别,年龄,职位,薪水),提供3个构造方法,可以初始化(1) (名字,性别,年龄,职位,薪水), (2) (名字,性别,年龄) (3)(职位,薪水),要求充分复用构造器

    Constructor方法重载
    public Employee(name,sex,age)
    public Employee(position,salary)
    public Employee(name,sex,age,position,salary){
    	this(name,sex,age)
    	//this(position,salary) this调用构造方法只能在第一行, 所以这俩属性手动初始化吧
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    13.将对象作为参数传递给方法。
    题目要求:
    (1)定义一个Circle类,包含一个double型的radius属性代表圆的半径, findArea()方法返回圆的面积。
    (2)定义一个类PassObject,在类中定义一个方法printAreas(), 该方法的定义如下:
    public void printAreas(Circle C, int times) //方法签名
    (3)在printAreas方法中打印输出1到times之间的每个整数半径值,以及对应的面积。
    例如,times为5, 则输出半径1, 2, 3, 4, 5, 以及对应的圆面积。
    (4)在main方法中调用printAreas()方法,调用完毕后输出当前半径值。程序运行结果
    如图所示

    image-20221107222800670

    14.扩展题
    有个人Tom设计他的成员变量成员方法,可以电脑猜拳. 电脑每次都会随机生成0, 1, 2
    0表示石头 1表示剪刀 2表示布
    并要可以显示Tom的输赢次数(清单)

    image-20221107223010823

  • 相关阅读:
    Es结合springboot(笔记回忆)
    服务器监控及其监控工具
    ceph trash 调研
    redis数据库基础知识
    再也不用为PDF文件修改发愁了?speedpdf一键转成Word
    入职java学习总结
    【从面试出发学习java】- Java - JVM
    Pytorch实用教程:Pytorch的nn.LSTM中参数的含义
    Rust编程中的线程间通信
    数字化转型导师坚鹏:数字化时代银行网点厅堂营销5大关键点分析
  • 原文地址:https://blog.csdn.net/Drifter_Galaxy/article/details/127748543