Java学习基础到深入5(类/方法调用与方法传参/利用数组返回多个值/递归)

本文详细介绍了Java中类的创建、属性和方法的使用,包括实例化对象、方法调用机制、参数传递以及递归调用。通过实例展示了如何进行对象间的属性共享、方法的必要性、数组和对象作为参数的传递方式,并探讨了递归在解决数学问题和算法中的应用。此外,还涉及到了方法的跨类调用,强调了方法调用时的权限和对象引用的概念。
摘要由CSDN通过智能技术生成

创建

  • 类的属性和方法创建
//类的属性和方法创建

public class ClassCreation {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.speak();
    }
}
class Person {
    String name;
    int age;
    public void speak() {
        System.out.println("ddsds");
    }
}
  • 要注意在类的创建过程中jvm中的内存机制:
public class ClassDemo {
    public static void main(String[] args) {
        Cat cat = new Cat();    //创建一个cat对象
        Cat cat1 = new Cat();    //创建cat1对象
        cat.name = "king";      //对cat赋值
        cat.age = 13;
        cat1 = cat;     //这里是引用赋值,cat1与cat共享一个堆空间,cat1改变,cat也会改变
//        cat1 = null;    //将cat1置空,使cat1与堆空间的连接断掉
        System.out.println("名称:" + cat.name + " " + "年龄:" + cat.age);
        System.out.println(cat1.name + " " + cat1.age);   //如果将cat1 = null,会使这里报错,因为此时cat1与cat已经没有了关系。
    }
}

class Cat{        //创建一个Cat类
    String name;
    int age;
}

方法调用机制

  • 当程序调用方法时,会开辟一个栈空间,然后就会按照计息算计系统课程中函数调用那一节的方法执行P过程和Q过程,最后得到返回值。
  • 方法的必要性:比如有一个二维数组需要遍历,用双重循环做,如果要对其进行10次遍历,代码量就会大大提升。而将遍历做成方法看,就调用十次放方法即可。
  • 重要!!!:一个方法最多有一个返回值,如果想返回多个返回值怎么办?
    • 答:可以将多个返回值利用数组存储起来,返回一个数组即可:
    	public class ClassCreation {
        public static void main(String[] args) {
            Person p1 = new Person();
            int[] pres = p1.speak(2,5);    //创建一个pres数组接受返回类型为数组的值
            System.out.println(pres[0] + " " + pres[1] );    //输出得到的数组
        }
    }
    class Person {
        String name;
        int age;
        public int[] speak(int m, int n) {   //定义int[]类型
            int[] res = new int[2];
            res[0] = m + n;
            res[1] = m - n;
            return res;
        }
    }
    
  • 方法里面不可以再定义方法,但是可以调用方法。

跨类方法调用

  • 同包下的不同类之间的方法调用:需要被调用的函数时public类型。并且需要调用时先创建被调用函数所在类的对象:
public class MethodCall1 {
    public static void main(String[] args) {
        A a = new A();
        a.f1();
    }
}
class A {
    public void f1() {
        System.out.println("调用了f1");
        B b = new B();   //创建类B的对象b
        b.f2();
    }
}
class B {
    public void f2(){
        System.out.println("f2被调用");
    }
}

方法传参机制

  • 注:当实参和形参是数组,对象时,都是引用传递。传的是地址,可以通过形参影响实参。
  • 当参数为对象时
public class Method {
    public static void main(String[] args) {
        Person1 per11 = new Person1();
        per11.age = 20;
        System.out.println(per11.age);
        Person2 per2 = new Person2();
        per2.per1(per11);
        System.out.println(per11.age);
    }
}
class Person1 {
    int age;
    String name;
}
class Person2 {
    public void per1(Person1 p){
        p.age = 10;
    }
}
  • 输出结果为20,10。说明对象传参为引用传参。
  • 当参数为数组时:
public class Method1 {
    public static void main(String[] args) {
        x1 x = new x1();
        int[] a = {1,2,3};
        x.aaa(a);
        System.out.println("调用函数后");
        for (int i = 0; i < a.length; i++){
            System.out.print(a[i] + " ");
        }
    }
}
class x1 {
    public int[] aaa(int[] p) {
        //传参前
        System.out.println("在函数中传参前");
        for (int i = 0; i < p.length; i++){
            System.out.print(p[i] + " ");
        }
        System.out.println();
        p[0] = 5;
        //传参后
        System.out.println("在函数中传参后");
        for (int i = 0; i < p.length; i++){
            System.out.print(p[i] + " ");
        }
        System.out.println();
        return p;
    }
}
  • 输出结果:
    在这里插入图片描述
  • 发现数组和对象传参时都是引用传参,形参会改变实参。
  • 如果想创建与原来对象独立相同的一个对象,则在函数里新创建一个对象,将原对象的属性赋值给新对象,再返回新对象即可。

方法递归调用

  • 递归能解决什么问题
    • 各种数学问题,8皇后问题,汉诺塔,阶乘问题,迷宫问题,球和篮子的问题
    • 各种算法中也会用到递归,比如快排,归并排序,二分查找,分治算法
  • 递归在栈中,先找到最里层的函数和值,依次往外输。
  • 求n的阶乘:
public class Factorial {
    public static void main(String[] args) {
        Factorial1 p = new Factorial1();
        double op = p.factorial2(4);
        System.out.println(op);
    }
}
class Factorial1 {   //阶乘类
    public double factorial2(int n) {   //方法
        if(n == 1){
            return 1;
        }else {
            return factorial2(n - 1) * n;   //n * (n-1) * ...
        }
    }
}

斐波那契数列(递归)

  • 1,1,2,3,5,8,13…,给出一个n,求值为多少?
  • 思路:如果n == 1 || n == 2 时会返回1;其他情况等于f(n - 1 ) + f (n - 2);
  • 代码:
import java.util.Scanner;

public class Feibonaqi {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int index = input.nextInt();
        Sa sa = new Sa();
        int res = sa.feibonaqi(index);
        System.out.println(res);

    }
}
class Sa {
    public int feibonaqi(int n) {
        if(n == 1 || n == 2) {
            return 1;
        }else if(n == 0){
            return 0;
        }else {
            return feibonaqi(n -1) + feibonaqi(n - 2);
        }
    }
}

老鼠走迷宫(韩顺平老师讲得真的好!!)

  • 如图:
    在这里插入图片描述

  • 问题:如图的迷宫,老鼠需要从(1,1)这个位置走到(6,5)这个位置,需要找到该路径

  • 原迷宫:

    • 1表示障碍,0表示可以走的位置
    • 思路:为什么用递归:因为是要从一个方向走,知道找到该位置才可以
  • 代码:

public class Migong {
    public static void main(String[] args) {
        int[][] map = new int[8][7];
        for (int i = 0; i < map.length; i++) {
            for (int j =0; j < map[i].length; j++) {
                if (i == 0 || i == 7) {
                    map[i][j] = 1;
                }else if(j == 0 || j ==6) {
                    map[i][j] = 1;
                }else {
                    map[i][j] = 0;
                }
            }
        }
        map[3][1] = 1;map[3][2] = 1;
        A1 a1 = new A1();
        a1.findWay(map,1,1);
        for (int i = 0; i < map.length; i++){
            for(int j = 0; j < map[i].length; j++) {
                System.out.print(map[i][j] + " ");
            }
            System.out.println();
        }

    }
}

//int[][] map 表示这个迷宫的二维数组
//i,j表示当前位置
//0表示二维数组中不为1,即不为障碍物;1表示障碍物;2表示能走通;3表示走过但不通;
//可以将递归看成一个自动的过程,直到遇到结束标志后停止
//从代码的递归顺序可以看出,优先顺序为下,右,上,左
class A1 {
    public boolean findWay(int[][] map, int i, int j) {
        if (map[6][5] == 2){    //结束标志
            return true;
        }else {
            if (map[i][j] == 0) {    //判断能不能走通的关键
                map[i][j] = 2;
                if (findWay(map, i + 1, j)) {   //向下走优先
                    return true;
                }else if (findWay(map, i, j + 1)){
                    return true;
                }else if (findWay(map, i - 1, j)) {
                    return true;
                }else if (findWay(map, i, j-1)) {
                    return true;
                }else {
                    map[i][j] = 3;
                    return true;
                }
            }else {
                return false;
            }
        }

    }
}

汉诺塔问题

  • 思路,利用递归:
    1. 先判断盘子个数,也是递归的停止条件m == 1
    2. 整体思路为无论多少个盘子,始终看成2个,一个是最下面的,一个是上面m - 1 个盘子,也就是说把m - 1个盘子看成一个整体。
    3. 所以思路就是先将m - 1个盘子移到B柱,再将A柱上的一个盘子移到C柱,最后将B柱的移到C 柱。如此形成一个递归。
  • 代码:
public class Hanoi {
    public static void main(String[] args) {
        Test test = new Test();
        test.test1(3 , 'a' , 'b', 'c');
    }
}
class Test {
    public void test1(int m, char a, char b, char c) {
        if (m == 1){
            System.out.println(a + "->" + c);
        }else {
            //借助c,将m-1个盘移动到b
            test1(m -1, a, c, b);
            //将最后一个盘移动到c
            System.out.println(a + "->" + c);
            //借助a,将b上m-1盘移动到c
            test1(m - 1, b, a, c);
        }
    }
}
  • 结果如图:
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xinshuai9333

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值