B站韩顺平学Java课程——个人笔记(第7章):方法,类,对象,递归。递归思维解决——斐波那契数,猴子吃桃,迷宫,汉诺塔等

1.简介

        俺就一小白,半途想记录一下,有错就改,这当自己的小笔记,知识点细小了一点,欢迎大家补充,同时愿自己坚持下来。很多知识点都在代码里面备注,为了方便自己就不一一拿出来了。主要内容:Java方法,类,对象,递归。递归思维解决——斐波那契数,猴子吃桃,迷宫,汉诺塔等。目录齐全。

来源:韩顺平 零基础30天学会Java

2.类和对象

类和对象:
    类是创建一个数据类型;
    对象就是一个具体的事物。
public class Object_Base01 {
    /*
    类和对象:
        类是创建一个数据类型;int,char.double
        对象就是一个具体的事物。
     */

    public static void main(String[] args) {
        /*
        张老太养了两只猫猫:一只名家叫小白,今年3岁,白色。
        还有一只叫小花,今年100岁,花色。请编写一个程序,
        当用户输入小猫的名字时就显示该猫的名字,年龄,颜色。
        如果用户输入的小猫名错误,则显示 张老太没有这只猫猫。
         */
//        //1.单独变量==》1)不利于数据的管理; 2)效率低下
//        String dog1Name = "小白";
//        String dog2Name = "花花";
//
//        int dog1Age = 18;
//        int dog2Age = 38;
//
//        //2.数组==》1)数据类型无法体现 2)只能通过下标表现出来
//        String dog1[] = {"小白", "18", "白色"};
//        String dog2[] = {"小花", "38", "花色"};

        //3.数组
        //实例化一个对象
        Cat cat1 = new Cat();   //创建一只猫,并赋值给 cat1
        cat1.name = "小白";
        cat1.age = 18;
        cat1.color = "白色";
        cat1.weight = 23.34;

        //cat2 是对象名(对象引用)
        //new Cat() 创建的对象空间才是真正的对象
        Cat cat2 = new Cat();
        cat2.name = "小花";
        cat2.age = 38;
        cat2.color = "花色";
        cat2.weight = 9.32;

        //怎么访问
        System.out.println("第一只猫" + cat1.name + "\t" + cat1.age
         + "\t" + cat1.color + "\t" + cat1.weight);
        System.out.println("第二只猫" + cat2.name + "\t" + cat2.age
         + "\t" + cat2.color + "\t" + cat2.weight);

    }
}
class Cat{
    // 属性/成员变量/字段
    String name;
    int age;
    String color;
    double weight;
    // 属性既可以是基本数据类型,也可以是引用类型(数组,对象)


        //创建空间的方法:
        // 1)直接创建;Cat cat = new Cat()
        // 2)先声明再创建: Cat cat;       caty = new Cat()

        //访问属性:
        // 对象名.属性名


        //类与对象
        /*
        Java 内存的结构分析
        1.栈:一般存放基本数据类型
        2.堆:存放对象(Cat cat,数组等)
        3.方法区L:常量区(常量,比如字符串),类加载信息
        4.示意图[Cat(name,age,prince]
         */
//        Person p = new Person();
//        p.name = "jack";
//        p.age = 10;
        /*
        创建对象流程简单分析:
        1.先加载Person类信息
        2.在堆中分配空间,进行默认初始化
        3.把地址给p,p指向的对象
        4.进行指定初始化  p.name = "jack";  p.age = 10;
         */

}

3.方法

方法调用:
// 1.方法写好后,不去调用,不会输出
// 2.先创建一个对象,再去调用
方法调用小结:
//1.当程序执行到方法时,就会开辟一个独立的空间(栈空间)
//2.当方法执行完毕,或者执行到return语句时,就会返回
//3.返回到调用的地方
//4.返回后继续执行方法后的语句
public class Method_02 {
    public static void main(String[] args) {
        //方法调用:
        // 1.方法写好后,不去调用,不会输出
        // 2.先创建一个对象,再去调用
        Person p1 = new Person();
        p1.name = "皓泽";
        p1.speak();
        p1.cal01();
        p1.cal02(5);
        int returnRes = p1.getSum(2,34);    //调用getSum,同时进行赋值
        System.out.println("getSum返回值:" + returnRes);
        System.out.println(p1.name);
    }
}

class Person{
    String name;
    int age;

    // 1. public 表示方法是公开的
    // 2. void: 表示方法没有返回值
    // 3.speak() speak是方法名, ()形参列表
    // 4. {}方法体, 可以写物品,要执行的代码
    public void speak(){
        System.out.println("我是帅比");
    }

    //添加cal01 成员方法,计算1-1000的和
    public void cal01(){
        int res = 0;
        for (int i = 0; i <= 1000; i++) {
            res += i;
        }
        System.out.println("计算结果为:" + res);
    }

    //添加cal02 成员方法,计算1-n的和
    //解读:
    //1.(int n) 形式列表, 表示当前有一个形参 n,可以从用户输入
    public void cal02(int n){
        int res1 = 0;
        for (int i = 0; i <= n; i++) {
            res1 += i;
        }
        System.out.println("计算结果:" + res1);
    }

    //添加getSum成员的方法,可以计算两个数的和
    //解读:
    // 1.public 表示方法是公开的
    // 2.int :表示方法执行后,返回一个 int 值
    // 3.getSum 方法名
    // 4.(int num1, int num2) 形参列表,2个形参,可以接受用户传入的两个数
    public int getSum(int num1,int num2) {
        int res = num1 + num2;
        return res;     //return语句


        //方法调用小结:
        //1.当程序执行到方法时,就会开辟一个独立的空间(栈空间)
        //2.当方法执行完毕,或者执行到return语句时,就会返回
        //3.返回到调用的地方
        //4.返回后继续执行方法后的语句

    }
}

4.为什么需要成员方法

1.成员方法的好处:
//    提高代码的复用性
//    可以将实现的细节封装起来然后供其他用户来调用即可。
public class Method_03 {
    //为什么需要成员方法

    public static void main(String[] args) {
        int map[][] = {{1,2,4},{3,5,9},{6,4,2}};
        Mytool tool = new Mytool();
        tool.printArr(map);
        tool.printArr(map);
        tool.printArr(map);
    }
}

class Mytool{   //类
    //定义一个输出数组方法

    public void printArr(int map[][]){
        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();
            System.out.println("==========");
        }
    }
}
public class MethodDetail_04 {

    //1.一个方法最多有一个返回值    【思考:如何返回多个值:可以使用数组】
    public static void main(String[] args) {
        AA a = new AA();
        int res[] = a.getSumAndSub(6,4);
        System.out.println("和 = " + res[0]);
        System.out.println("差 = " + res[1]);
    }
}
class AA{
    //和 与 差
    public int[] getSumAndSub(int n1,int n2){

        int resArr[] = new int[2];  //创建一个数组
        resArr[0] = n1 + n2;
        resArr[1] = n1 - n2;
        return resArr;
    }

    //2..返回类型可以为任意类型,包含基本类型或引用类型(数组,对象)
    //  看上述代码getSumAndSnb

    // 3.如果方法要求有返回数据类型,则方法体中最后的执行语句必须为return 值;而且要求返回值类型必须和return的值类型一致或兼容
    public double f1(){     //要求

        double d1 = 1.1 * 3;
        int a = 100;
        return a;     //返回  //int->double   兼容
    }

    // 4.如果方法是void,则方法体中可以没有return语句,或者 只写 return;

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


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

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

    /*
    三.方法调用细节说明
    1.同一类中可以直接调用
    2.跨类的方法调用,需要通过对象名调用------类似于 main 调用 class 类
    3.*跨类的方法调用和方法的访问修饰符相关(后面细讲)
     */




}

练习题

public class MethodExercise_05 {
    public static void main(String[] args) {
        BA b = new BA();
        boolean c = b.num(1);
        System.out.println(c);  //接受return的返回值

        //BA d = new BA();
        b.print(4,32,'#');
    }
}
//编写一个类 AA,判断一个数是奇数还是偶数,返回boolean
class BA{
    public boolean num(int a) {
//        if(a % 2 == 1){
//            return true;
//        }else{
//            return false;
//        }
        return (a % 2 == 1) ? true : false;
    }


    //按要求,输出对应的行和列的字符
    public void print(int row,int col,char c){
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                System.out.print(c);
            }
            System.out.println();
        }
    }
}
import java.util.Scanner;

public class MethodParameter_06 {
    //成员方法传参机制
    // 1.形参的任何变化都不会影响实参;
    // 2.引用类型传递的是地址,可以通过形参来影响实参;
    //      形参和实参指向同一个存储地址空间,因此,形参改变空间的内容,会对地址空间内容发生永久性变化
    //3.
    public static void main(String[] args) {
        Scanner myScanner = new Scanner(System.in);
        System.out.print("输入第一个数 = ");
        int a = myScanner.nextInt();
        System.out.print("输入第二个数 = ");
        int b = myScanner.nextInt();
        AAA c = new AAA();
        c.swap(a,b);

    }
}

class AAA{
    public void swap(int a,int b){
        System.out.println("交换前\n a = " + a + "\t" +  "b = " + b);
        a = a + b;
        b = a - b;
        a = a - b;
        System.out.println("交换后\n a = " + a + "\t" + "b = " + b);
    }
}

克隆方法

public class MethodExercise_07 {
    //克隆对象:要求新对象与旧对象是两个独立的对象,且属性相同
    public static void main(String[] args) {

        Persons p = new Persons();
        p.name = "minhao";
        p.age = 19;

        MyTools tools = new MyTools();  //创建一个tools对象
        Persons p2 = tools.copyPersons(p);

        //到此 p 和 p2是person对象,但是是两个独立的对象,属性相同

        System.out.println("age1 = " + p.age + "\t" +  "name1:" + p.name);
        System.out.println("age2 = " + p2.age + "\t" +  "name2:" + p2.name);
        System.out.println("p == p2");
    }
}
class Persons{
    String name;
    int age;
}

class MyTools{
    public Persons copyPersons(Persons p){
        //创建一个新对象
        Persons p2 = new Persons(); //方法之间的调用
        p2.name = p.name;//把原来对象的名字赋给p2.name
        p2.age = p.age;//把原来对象的年龄赋给p2.age

        return p2;
    }
}

5.递归

1)递归的重要规则

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

public class Recursion_08 {


    //递归:自己调用自己
    public static void main(String[] args) {
        T t1 = new T();     //定义一个对象t1
        t1.test(9);
        //Scanner myScanner = new Scanner(System.in);
        //int i = myScanner.nextInt();
        int res = t1.factorial(5);
        System.out.println("res=" + res);
    }
}

class T{
    public void test(int n){
        if (n > 2){
            test (n - 1);
        }
            System.out.println("n = " + n);
    }
    public int factorial(int n){    //阶乘
        if (n==1){
            return 1;
        }else{
            return factorial(n - 1) * n;
        }
    }
}

2)斐波那契数(必备)

3)猴子吃桃(蓝桥杯)

import java.util.Scanner;

public class RecursionExercise_09 {
    public static void main(String[] args) {
        Scanner myScanner = new Scanner(System.in);
        System.out.println("你想知道第几个数的斐波那契数:");
        int n = myScanner.nextInt();

        M m1 = new M();

        //斐波那契数
        if(m1.fibonacci(n) != -1) {
            System.out.println("当n = " + n + "时对应的斐波那契数 = " + m1.fibonacci(n));
        }else{
            System.out.println("滚");
        }

        //猴子吃桃
        System.out.println("你想知道第几天的桃子数量:");
        int day = myScanner.nextInt();
        int peachNum = m1.peach(day);
        if(peachNum != -1){
            System.out.println("第"+ day + "天的桃子数量为" + m1.peach(day));
        }else{
            System.out.println("滚");
        }


    }
}

class M {
    /*递归写出斐波那契数:1,1,2,3,5,8,13......给你一个整数,求出他的值是多少
    思路:
    1.n = 1;斐波那契数 = 1
    2.n = 2;斐波那契数 = 1
    3.n = 3;斐波那契数 = 2
    4.n = 4;斐波那契数 = 3
     */
    public int fibonacci(int n) {
        if (n >= 1) {
            if (n == 1 || n == 2) {
                return 1;
            } else {
                return fibonacci(n - 1) + fibonacci(n - 2);
            }
        } else {
            System.out.println("你的输入有误");
            return -1;
        }
    }
    /*
    猴子吃桃子问题:有一堆桃子,猴子第一天吃了其中的一半,并再多吃了一个!
    以后每天猴子都吃其中的一半,然后再多吃一个。当到第10天时,想再吃时(即还没吃),
    发现只有1个桃子了。问题:最初共多少个桃子?
    思路:
    1. 第10天,1个桃子
    2. 第9天,(day10 + 1) * 2 = 4个桃子
    3. 第8天,(day9 + 1) * 2 = 10个桃子
     */
    public int peach(int day){
        if(day == 10){
            return 1;
        }else if(day >= 1&&day <= 9){
            return (peach(day + 1) + 1) * 2;
        }else{
            System.out.println("day的范围不在规定内");
            return -1;
        }
    }
}

4)迷宫

public class MiGong_10 {
    public static void main(String[] args) {
        //思路:
        //1.创建八行其列的迷宫,用二维数组表示
        //2.先规定 map 数组的元素值: 0 表示可以走, 1 表示不能走
        int map[][] = new int[8][7];

        //3.将第一行和最后一行设置为 1
        for (int i = 0; i < 7; i++) {
            map[0][i] = 1;
            map[7][i] = 1;
        }

        //4.将最左边和最右边的设置为 1
        for (int i = 0; i < 8; i++) {
            map[i][0] = 1;
            map[i][6] = 1;
        }

        //5.剩余障碍物
        map[3][1] = 1;
        map[3][2] = 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();
        }

        //使用findway给老鼠找路
        G g1 = new G();
        g1.findway(map,1,1);//引用传递

        System.out.println("\n===========找路的情况==========");

        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();
        }

    }
}

class G{

    //递归回溯思想解决问题
    //      回溯现象:
    //      扩展:求出最短路径       a.穷举法 b.图

    // 1.findway方法就是用来找出迷宫路径
    // 2.找到返回true 否则返回false
    // 3.map 就是二维数组,即表示迷宫
    // 4.i,j就是老鼠的位置,初始化位置【1.1】
    // 5.因为是递归找路,先规定要求
    //      0 表示可以走, 1 表示障碍物,2 表示可以走, 3 表示走过,但不能走通
    // 6.当map[6][5] = 2 时,就表明找到通路了,否则继续找
    // 7.选择合适的策略下-->右-->上-->左
    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)){//右
//                    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;
//                }
                //上-->右-->下-->左
                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{//map[i][j] = 1,2,3
                return false;
            }
        }
    }
}

5)汉诺塔

public class HanoiTower_11 {
    public static void main(String[] args) {

        Tower tower = new Tower();
        tower.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){
        //如果 num = 1
        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);
        }

    }
}

6.方法重载

public class OverLoad_12 {
    public static void main(String[] args) {
        /*
        方法重载:
        1. 方法名相同
        2. 形参列表:必须不同(个数不同,类型不同,顺序不同,参数名无要求)
        3. 返回值,无要求
         */

        /*1.编写程序,类Methods中定义三个重载方法。方法名为m。三个方法分别接受一个int参数,两个int参数
            一个字符串参数。分别执行平方运算并输出结果,相乘并输出结果,输出字符串信息。在主类main()方法中分别
            用参数区别调用三个方法。
        */
        Methods methods = new Methods();
        methods.m(8);
        methods.m(6,9);
        methods.m("旧人已故");

        /*2.在Methods类,定义三个重载方法max(),第一个方法,返回两个int值中的最
        大值,第二个方法,返回两个double值中的最大值,第三个方法,返回三个
        double值中的最大值,并分别调用三个方法。
         */
        methods.max(6,9);
        methods.max(10.01,9.6);
        methods.max(10.1,9.6,2.5);

    }
}

class Methods{
    public void m(int n){
        System.out.println("平方结果 = " + (n * n));
    }

    public void m(int n,int a){
        System.out.println("相乘结果 = " + (n * a));
    }

    public void m(String b){
        System.out.println("传入的String = " + b);
    }

    public void max(int a,int b){
        int max = a > b ? a : b;
        System.out.println("两者中的最大值 = " + max);
    }

    public void max(double a,double b){
        double max = a > b ? a : b;
        System.out.println("两者中的最大值 = " + max);
    }

    public void max(double a,double b,double c){
        double max = a > (b > c ? b : c) ? a : (b > c ? b : c);
        System.out.println("两者中的最大值 = " + max);
    }

}

7.可变参数

public class VarParamenter_13 {
    public static void main(String[] args) {
        /*可变参数
        基本概念:
            java允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法就可以通过可变参数实现
        基本语法:
             访问修饰符 返回类型 方法名(数据类型.. 形参名){
             }
         */
        HspMethod m = new HspMethod();
        System.out.println(m.sum(100,50,10));
        System.out.println(m.sum(12,56,766));
    }
}

class HspMethod{
    // 1.int...表示接受的是可变参数,类型是int
    // 2.使用可变参数时,可以当作是数组
    public int sum(int... nums){
        System.out.println("接受的参数个数:" + nums.length);
        int res = 0;
        int sum = 0;
        for (int i = 0; i < nums.length; i++) {
            res += nums[i];
        }
        return res;
    }
}

细节

public class VarParamenterDetail_14 {
    public static void main(String[] args) {
        /*
        注意事项:
        1. 可变参数的实参可以为0个或任意多个
        2. 可变参数的实参可以为数组
        3. 可变参数的本质是数组
        4. 可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后
        5, 一个参数列表中只能出现一个可变参数
         */

        //细节: 可变参数的实参可以为数组
        int arr[] = {1,2,3};
        TT t = new TT();
        t.f1(arr);
    }
}
class TT{
    public void f1(int... nums){
        System.out.println(nums.length);
    }

    //细节: 可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后
    public void f2(double str,double... nums){
        System.out.println();
    }
}

8.作用域

public class VarScope_16 {
    public static void main(String[] args) {
        /*
        P237.
        (变量)作用域基本使用:
        1. 全局变量:也就是属性,作用域为整个类体
        2. 属性在定义时,可以直接赋值
        3. 局部变量:一般是指变量方法中定义的变量,作用域为定义他的代码块
        4. 全局变量(属性)可以不赋值,直接使用,因为有默认值,局部变量必须赋值后
            才可以使用,因为没有默认值。
         */



        /*
        P238-P239
        作用域使用细节 Detail
        1. 属性和局部变量可以重名,访问时遵循就近原则
        2. 在同一个作用域中,比如在同一个成员方法中,两个局部变量,不能重名。
        3. 属性生命周期较长,伴随对象的创建而创建,伴随着对象的销毁而销毁。
            局部变量,生命周期较短,伴随着它的代码块的执行而创建,伴随着代码块的结束而销毁。
            即在一次方法调用过程中
        4. 作用域的范围不同:
            全局变量/属性:可以被本类或其他类使用(通过对象调用)
            局部变量:只能在本类中使用
        5. 修饰符不同
            全局变量/属性 可以加修饰符
            局部变量 不可以加修饰符
         */

    }
}

9.构造器/构造方法

构造器的细节

//构造器的细节:
//1. 一个类可以定义多个构造器,即构造器重载
Personn p1 = new Personn("minhao");
System.out.println("p1 name = " + p1.name);
// 2.构造器名要和类名一致
// 3.构造器没有返回值

// 4.构造器是完成对象的初始化,并不是创建对象
// 5.在创建对象时,系统自动的调用该类的构造方法
//eg:p1.name = ...      (错误)只能由系统调用
public class Construuctor_17 {
    public static void main(String[] args) {
        /*
        P240
        构造方法/构造器
        ●看一个需求
        我们来看一个需求:前面我们在创建人类的对象时,是先把一个对象创建好后,
        再给他的年龄和姓名属性赋值,如果现在我要求,在创建人类的对象时,
        就直接指定这个对象的年龄和姓名,该怎么做?这时就可以使用构造器
        ● 基本语法
            ·[修饰符]方法名(形参列表){
                方法体;
            }
        老韩说明:
        1)构造器的修饰符可以默认,也可以是public,protected,private
        2)构造器没有返回值
        3)方法名 和类名字必须一样
        4)参数列表 和 成员方法-样的规则
        5)构造器的调用,由系统完成

        基本介绍:
        构造方法又叫构造器,是类的一种特殊的方法,他的作用主要是
        完成对新对象的初始化。特点如下:
        1.方法名和类名相同
        2.没有返回值
        3.在创建对象是,系统会自动的调用和该类的构造器完成对对象的初始化
         */


        //P241构造器的快速入门
        //在构造人类对象时,直接定义这个对象的年龄和姓名
        Personn p = new Personn("haoze",18);
        System.out.println("p的信息如下");
        System.out.println(p.name);
        System.out.println(p.age);



        //P242-P243
        // 构造器的细节:
        //1. 一个类可以定义多个构造器,即构造器重载
        Personn p1 = new Personn("minhao");
        System.out.println("p1 name = " + p1.name);
        // 2.构造器名要和类名一致
        // 3.构造器没有返回值

        // 4.构造器是完成对象的初始化,并不是创建对象
        // 5.在创建对象时,系统自动的调用该类的构造方法
        //eg:p1.name = ...      (错误)只能由系统调用

        // 6.如果程序员没有定义构造器,系统会自动给类生成一个默认无参构造器
        Dog dog = new Dog();
        // 7.一旦定义了自己的构造器,默认无参构造器就会被覆盖,不能使用,除非显式的定义一下
        //即: Dog(){}
        Dog dog1 = new Dog("zhaomin");
    }
}

class Dog{
    //如果程序员没有定义构造器,系统会自动给类生成一个默认无参构造器
    //javac 反编译
    /*
    默认构造器
    Dog(){

    }
     */
    //一旦定义了自己的构造器,默认无参构造器就会被覆盖,不能使用,除非显式的定义一下
    public Dog(String dName){
        //...
    }

    Dog(){      //显式的定义一下

    }
}

class Personn{//此处用Personn是因为在同一文件夹下,我的Person已经定义过类了
    String name;
    int age;
    // 1.没有返回值,故没有void
    // 2.构造器的名称与类的名称一样,都为Personn
    // 3.(String pName,int pAge) 时构造器形参列表,规则与成员方法一样
    public Personn(String pName,int pAge){
        System.out.println("构造器被调用~~完成对象属性的初始化");
        name = pName;
        age = pAge;
    }
    public Personn(String pName){
        name = pName;
    }

}

10.对象创建流程分析(面试题)

String 是引用类型 所以在常量区调用地址

Java 内存的结构分析
        1.栈:一般存放基本数据类型
        2.堆:存放对象(Cat cat,数组等)
        3.方法区L:常量区(常量,比如字符串),类加载信息

11.this

thisDetail

public class ThisDetail_19 {
    public static void main(String[] args) {
        /*
        ThisDetail.java
        1.this关键字可以用来访问本类的属性、方法、构造器
        2.this用于区分当前类的属性和局部变量
        3.访问成员方法的语法:this.方法名(参数列表);
        4.访问构造器语法:this(参数列表);注意只能在构造器中使用(只能构造器中访问另一个构造器
        5.this不能在类定义的外部使用,只能在类定义的方法中使用。
        */

        Tf t2 = new Tf();

        //3.访问成员方法的语法:this.方法名(参数列表);
        t2.f2();
        t2.f3();

    }
}

class Tf{
    String name = "tom";
    int num = 100;
    // 访问构造器语法:this(参数列表)
    // 4.访问构造器语法:this(参数列表);注意只能在构造器中使用(只能构造器中访问另一个构造器,必须放在第一条语句)

    //注意:访问构造器语法:this(参数列表);必须放在第一条语句(与继承有关)

    public Tf(){
        this("tom",12);//必须放在第一条语句
        System.out.println("Tf() 构造器");

    }
    public Tf(String name,int age){
        System.out.println("Tf(String name,int age) 构造器");

    }


    public void f3(){
        String name = "jack";
        int num = 99;
        //传统方法          就近原则
        System.out.println("name=" + name + "\t" + "num = " + num);
        //this调用        属性
        System.out.println("name=" + this.name + "\t" + "num = " + this.num);
    }
    //3.访问成员方法的语法:this.方法名(参数列表);
    public void f1(){
        System.out.println("f1()方法..");
    }
    public void f2(){
        System.out.println("f2()方法..");
        //调用f1
        //方法1:
        f1();
        //方法2:
        this.f1();//继承细讲
    }

}

Exercise

public class ThisExercise_20 {
    public static void main(String[] args) {
        /*
        定义Person类,里面有name、age属性,并提供compareTo比较方法,用于判断是否和另一个人相等,
        提供测试类TestPerson用于测试,名字和年龄完全-:一样,就返回true,否则返回false
         */
        Monkey m1 = new Monkey("monkey",20);
        Monkey m2 = new Monkey("monkey",18);
        System.out.println("m1和m2的比较结果 = " + m1.compareTo(m2));
    }
}
class Monkey{
    String name;
    int age;
    //构造器
    public Monkey(String name,int age){
        this.name = name;
        this.age = age;
    }
    //compareTo比较方法
    public boolean compareTo(Monkey p){
        return this.name.equals(p.name) && this.age == p.age;
    }
}

  • 19
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值