Java 类和对象

65 阅读4分钟

类与对象

类 (自定义的数据类型) (抽象的事物) -> (实例化, 具体的实例) 对象

对象

  • 属性 (对象的特征)
  • 方法 (对象的行为)

对象是引用类型, 其内存分布为:

对象是指 堆中的地址以及其指向; cat 是对象的引用(对象名)

public class test1 {
    public static void main(String[] args) {
        // 创建Person对象
        // p1 是对象名(对象引用, 只是一个代号~)
        // new Person() 创造的对象空间 是真正的对象
        Person p1 = new Person();
        // 对象的属性默认值 遵守之前的规则 int 0 short 0 byte 0 long 0 
        System.out.println("当前对象信息:");
        System.out.println(p1.age +" "+p1.name +" "+p1.sal +" "+p1.isPass);
    }
}

class Person {
    // 对象 属性
    int age;
    String name;
    double[] sal;
    boolean isPass;
}

成员变量 = 属性 = field (字段) 可以为基本类型 or 引用类型

属性的定义与变量的定义类似, 但多了个访问修饰符 -> 控制属性的访问范围

成员属性

Java内存的结构分析

  1. 栈: 一般存放基本数据类型 (局部变量)
  2. 堆: 存放对象(Person person, 数组等...)
  3. 方法池: 常量池(常量 如字符串, 数), 类加载的信息

成员方法

方法的调用机制

public class test1 {
    public static void main(String[] args) {
        Person p1 = new Person();
        int resNum = p1.getSum(2, 5);
        System.out.println("getSum方法返回的值="+resNum);
    }
}

class Person {
    // 对象 = 属性+方法
    int age;
    String name;
    // (int a, int b) 为形参列表, 里面有两个参数 
    public int getSum(int a,int b){
        int res = a + b;
        return res;
    }
}

成员方法的好处:

  • 提高代码的复用性
  • 可以将实现的细节封装起来, 然后供其他用户来调用~

方法形参和实参的类型要一致或兼容、个数、顺序要一致, 方法体不能嵌套方法

方法传参机制

可传基本数据类型 也可传引用数据类型

public class test1 {
    public static void main(String[] args) {
        Person p = new Person();
        p.name = "sam";
        p.age = 100;
        // 创建Tools
        MyTools myTools = new MyTools();
        Person p2 = myTools.CopyPerson(p);
        System.out.println(p.name + p.age);
        System.out.println(p2.name + p2.age);
        System.out.println(p.hashCode()); // 可用于比较是否存储同一个对象
        System.out.println(p2.hashCode());
    }
}

class MyTools {
    public Person CopyPerson(Person p) { // 这里的 Person类 p 和 新建的Person类 p2 是不一样的~
        // 创建新对象
        Person p2 = new Person();
        p2.name = p.name; // 将原来对象名 赋给 p2
        p2.age = p.age;
        return p2;
    }
}

class Person {
    String name;
    int age;
}

递归

递归执行: 一开始压栈 然后(栈)从上到下返回 (弹栈)

递归重要原则

  1. 执行一个方法时, 就创建一个新的受保护的独立空间(栈)
  2. 方法的局部变量是独立的, 不会互相影响
  3. 如果方法中使用的是引用类型变量(如: 数组, 对象...), 就会共享该引用类型的变量
  4. 递归函数需要有出口(递归结束的条件! ),否则会有无限递归 -> 栈溢出
  5. 当一个方法执行完毕, 或遇到return, 就会返回, 遵守谁调用, 就把结果返回给谁~
public class test1 {
    // 猴子吃桃子问题, 有一堆桃子, 猴子第一天吃了其中的一半, 并再多吃一个, 以后的日子都是这样, 直至第10天时, 
    // 想再吃时, 发现只有1个桃子了, 问: 最初有多少个桃子 ?
    public static void main(String[] args) {
        int ans = fun(1); // 这里输入的天数参数可以自定义
        System.out.println(ans);
    }
    // 使用递归解决: 前一天的桃子数 = (后一天的桃子数+1) * 2
    public static int fun(int day) {
        if (day == 10) {
            return 1;
        } else if (day >= 1 && day <= 9) {
            return (fun(day + 1) + 1) * 2;
        } else {
            System.out.println("非法输入");
            return -1;
        }
    }
}

迷宫示意图:

public class test1 {
    // 老鼠走迷宫
    // 创建迷宫: 8行7列, 规定元素值, 0表示可以走, 1表示不可以走
    public static void main(String[] args) {
        int[][] arr = new int[8][7];
        for (int i = 0; i < arr[0].length; i++) { // 上下都为1
            arr[0][i] = 1;
            arr[arr.length - 1][i] = 1;
        }
        for (int i = 0; i < arr.length; i++) { // 左右都为1
            arr[i][0] = 1;
            arr[i][arr[0].length - 1] = 1;
        }
        arr[3][1] = arr[3][2] = 1;
        System.out.println("地图情况");
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                System.out.print(arr[i][j] + " ");
            }
            System.out.println();
        }
        T t = new T();
        t.findWay(arr, 1, 1);
        System.out.println("寻路情况");
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                System.out.print(arr[i][j] + " ");
            }
            System.out.println();
        }
    }
}

class T {
    // 使用递归回溯的思想 去找迷宫的出路
    // 如果找到 返回true 否则, 返回 false
    // map 代表迷宫 
    // 规定map数组 值的含义: 0表示可以走 1表示障碍物 2表示可以走 3表示走过, 但走不通
    // 当map[6][5] = 2 时 说明已经能够走出迷宫了
    public boolean findWay(int[][] map, int i, int j) { // 可以配合bfs/dfs 来求解最短路径
        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 false;
                }
            } else {
                return false;
            }
        }
     }
}