【Java自学】搬砖中年人代码自学之路Lesson 7


又一课完事儿,真的是越学越麻烦了。。。

不过其实感觉还是挺好玩儿的,还是挺憧憬以后自己学完这些乱七八糟的东西之后能够写出点自己想写的东西的感觉的,就是不知道这一天什么时候到

最近又开始忙了,天天一堆的破事儿,上班之后想学点什么东西确实是很难

一方面要跟自己抢时间,需要挤出额外的时间来学习

另一方面要跟自己的惰性做斗争,工作之后确实是就想烂在床上不动,每个休息日的时候微信步数基本上都过不了百

最最难的部分就是要跟自己日益退化的吸收能力做斗争,明显感觉到现在学东西不如上学的时候快了,当时大学偷懒因为不想学高数选了语言类的专业,当时其实咬咬牙选计算机专业好了,毕竟对这个东西的兴趣其实一直就有

学习 = 战斗,以前是跟各种各样的考试战斗,现在是为了能够在奔四的路上让自己变得更之前战斗,希望能够胜利


🇺🇳        “万事万物皆对象”

一、理解"万事万物皆对象"

        > 在Java语言范畴中,我们都将功能、结构等封装到类中,通过类的实例化,来调用具体的功能、结构

                > Scanner、String等

                > 文件:File

                > 网络资源:URL

        > 涉及到Java语言与前端HTML、后端的数据库交互时,前后端的结构在Java层面交互时,都体现为类、对象

二、对象数组的内存解析的说明

        > 引用类型的变量,只可能存储两类值:null或地址值(包含变量的类型)

        > 如果对象数组值是null,那么通过"对象.属性"/"对象.方法"进行调用时,报错空指针

三、匿名对象的使用

        > 理解:创建的对象,没有显示的赋给一个变量名,即为匿名对象

        > 特征:匿名对象因为不存在变量名,所以只能调用一次

        > 使用:如下代码:

public class InstanceTest{
    public static void main(String[] args){
        Phone p = new Phone();
        System.out.println(p);//只new了对象,但是没有给对象赋值,输出的是地址值:com.eric.java.「Phone」@6b95977。其中「」括起来的部分是对象类型

        p.sendEmail();
        p.playGame();

        //匿名对象
        new Phone().sendEmail();
        new Phone().playGame();

        new Phone().price = 1999;
        new Phone().showPrice();//输出结果为0.0,因为上一条代码new的对象与本条代码new的对象并不是同一个

        PhoneMall phone = new PhoneMall();
        mall.show(new Phone());//这条代码即为对匿名对象的使用!这个过程调用的是同一个匿名对象
                               //实现的原理:【括号内的new Phone()确实是一个匿名对象,没有在栈空间内创建变量
                               //但是在调用show方法的过程中,这个匿名对象作为「PhoneMall类中的show方法的形参」
                               //却在栈空间里创建了变量,所以能够sendEmail之后再继续调用playGame】
    }
}

class PhoneMall{
    public void show(Phone phone){
        phone.sendEmail();
        phone.playGame();
    }
}

class Phone{
    double price;//价格
    public void sendEmail(){
        System.out.println("发送邮件");
    }
    public void playGame(){
        System.out.println("玩儿游戏");
    }
    public void showPrice(){
        System.out.println("手机的价格是:" + price);
    }
}

🇺🇳        方法的重载

一、方法的重载(overload)

        > 重载的概念:在同一个类中,允许存在一个以上的同名方法,只要他们的参数个数或参数类型不同即可

        > 判断是否是重载:"两同一不同"

                两同:同一个类、同一个方法名

                一不同:参数列表不同(参数个数不同、参数类型不同)

                ⚠️跟方法的权限修饰符、返回值类型、形参变量名、方法体都没有关系⚠️

        > 在通过对象调用方法时,如何确定某一个指定的方法?

                方法名 --> 参数列表

        > 重载的特点:与返回值类型无关,只看参数列表,且参数列表必须不同(参数个数或参数类型)。调用时,根据方法参数列表的不同来区别。示例:Arrays类中重载的sort() / binarySearch()等

//重载示例

//返回两个整数的和
int add(int x, int y){
    return x + y;
}

//返回三个整数的和
int add(int x, int y, int z){
    return x + y + z;
}

//返回两个小数的和
double add(double x, double y){
    return x + y;
}

🇺🇳        可变个数形参

        > JavaSE 5.0中提供了Varargs(variable number of arguments)机制,允许直接定义能和多个实参相匹配的形参。从而,可以用一种更简单的方式,来传递个数可变的实参

        > 具体使用

                > 可变个数形参的格式:数据类型 ... 变量名(参数名)

                > 当调用可变个数形参的方法时,传入的参数个数可以是:0个、1个、2个、....

                > 可变个数形参的方法与本类方法中方法名相同、形参不同的方法之间,构成重载

                > ⚠️可变个数形参的方法与本类方法中方法名相同、形参类型也相同的数组之间,不构成重载,二者不能共存

                > ⚠️可变个数形参在方法的形参中,必须声明在末尾

                > ⚠️可变个数形参在方法的形参中,最多只能声明一个可变形参️

        > JDK 5.0以前,只用数组形参来定义方法,传入多个同一类型变量

                public static void test(int a,String[] books);

        > JDK 5.0以后:采用可变个数形参来定义方法,传入多个同一类型变量

                public static void test(int a,String...books);

//可变个数形参示例:JDK5.0之前

public class MethodArgsTest{
    public static void main(String[] args){
        MethodArgsTest test = new MethodArgsTest();
        test.show(12);
        test.show("hello");
        test.show(new String[]{"AA","BB","CC"});
    }

    public void show(int i){

    }

    public void show(String s){
        System.out.println("show(String)");
    }

    public void show(int i,String...strs){
        
    }

//  public void show(String...strs,int i){//错误写法,报错提示:The variable argument type String of the method show must be the last parameter
//      
//  }
}
//可变个数形参示例:JDK5.0之后

public class MethodArgsTest{
    public static void main(String[] args){
        MethodArgsTest test = new MethodArgsTest();
        test.show(12);
        test.show("hello");
        test.show("hello","world");
        test.show("AA","BB","CC");
    }

    public void show(int i){

    }

    public void show(String s){
        System.out.println("show(String)");
    }

    public void show(String...strs){//可变个数形参
        for(int i = 0;i < strs.length;i++){//实际上就是把可变个数形参当作数组来看待,所以遍历的方式也跟数组相同
            System.out.println(strs[i]);
        }
    }
}

🇺🇳        Java的值传递机制

> 关于变量的赋值

        > 如果变量是基本数据类型,此时,赋值的是变量所保存的数据值

        > 如果变量是引用数据类型,此时,赋值的是变量所保存的数据的地址值

//值传递机制示例

public class ValueTransferTest{
    public static void main(String[] args){
        //基本数据类型
        int m = 10;
        int n = m;
        System.out.println("m = " + m + ",n = " + n);//m = 10,n = 10
        
        n = 20;
        System.out.println("m = " + m + ",n = " + n);//m = 10,n = 20

        //引用数据类型
        Order o1 = new Order();
        01.orderId = 1001;
        Order o2 = o1;//赋值之后,o1和o2的地址值相同,都指向堆空间中的同一个对象实体
        System.out.println("o1.orderId = " + o1.orderId + ",o2.orderId = " + o2.orderId);
                      //o1.orderId = 1001,o2.orderId = 1001;

        o2.orderId = 1002;
        System.out.println("o1.orderId = " + o1.orderId + ",o2.orderId = " + o2.orderId);
                      //o1.orderId = 1002,o2.orderId = 1002;
    }
}

class Order{
    int orderId;
}

> 方法的形参的传递机制:值传递

        > 形参:方法定义时,声明的小括号内的参数

        > 实参:方法调用时,实际传递给形参的数据

> 值传递机制:

        > 如果参数是基本数据类型,此时,实参给形参赋值的是实参真实存储的「数据值」

public class ValueTransferTest{
    public static void main(String[] args){
        int m = 10;
        int n = 20;
        System.out.println("m = " + m + ",n = " + n);//m = 10,n = 20

        //交换两个变量的值的操作 ==> 输出结果是可以成功交换两个变量的数据的
        int temp = m;
        m = n;
        n = temp;
        System.out.println("m = " + m + ",n = " + n);//m = 20;n = 10

        //测试是否可以通过swap方法达到数据交换的目的 ==> 输出结果是不能够交换两个变量的数据的
        ValueTransferTest test = new ValueTransferTest();
        test.swap(10,20);//方法执行完毕后就出栈销毁了
        System.out.println("m = " + m + ",n = " + n);//m = 10,n = 20,输出的结果实际上是main方法中的m和n
    }

    public void swap(int m,int n){
        int temp = m;
        m = n;
        n = temp;
    }
}

         > 如果参数是引用数据类型,此时,实参给形参赋值的是实参存储数据的「地址值」

public class ValueTransferTest{
    public static void main(String[] args){
        Data data = new Data();
        data.m = 10;
        data.n = 20;
        System.out.println("m = " + data.m + ",n = " + data.n);//m = 10,n = 20

        //直接交换m和n的值
        int temp = data.m;
        data.m = data.n;
        data.n = temp;
        System.out.println("m = " + data.m + ",n = " + data.n);//m = 20,n = 10

        //使用swap方法来交换m和n的值
        ValueTransferTest test = new ValueTransferTest();
        test.swap(data);//m = 20,n = 10;
                        //相当于是在swap方法的栈空间中创建了一个变量data,地址值跟main方法中的data的地址值是相同的
                        //所以通过swap方法中的data调用Data类中的属性并且进行交换,swap方法执行结束之后出栈
                        //通过main方法中的data调用Data中的属性的结果就是交换过来的
    }

    public void swap(Data data){
        int temp = data.m;
        data.m = data.n;
        data.n = temp;
    }
}

class Data{
    int m;
    int n;
}
//例题:
//1.定义一个Circle类,包含一个double型的radius属性代表圆的半径。一个findArea()方法来返回圆的面积
//2.定义一个类PassObject,在类中定义一个方法printArea(),该方法的定义如下:
//    > public void printArea(Circle c,int time)
//    > 在printArea方法中打印输出1到time之间的每个整数的半径值,以及对应的圆的面积
//3.在main方法中调用printArea()方法,调用完毕后输出当前的半径值

public class PassObject{
    public static void main(String[] args){
        PassObject test = new PassObject();
        Circle c = new Circle();
        test.printArea(c,5);
        System.out.println("当前半径值为:" + c.radius);
    }
    
    public void printArea(Circle c,int time){
        System.out.println("Radius\t\tArea");//标题行
        for(int i = 1;i < time;i++){
            c.radius = i;
            System.out.print(c.radius + "\t\t" + c.findArea());
        }
        System.out.println();
        c.radius = time + 1;
    }
}

class Circle{
    double radius;

    public double findArea(radius){
        return Math.PI * radius * radius;
    }
}
//体会Java的值传递机制
public class ValueTransfer{
    public static void main(String[] args){
        ValueTransfer test = new ValueTransfer();
        test.first();
    }

    public void first(){
        int i = 5;
        Value v = new Value();
        v.i = 25;
        second(v,i);
        System.out.println(v.i);
    }

    public void second(Value v, int i){
        i = 0;
        v.i = 20;
        Value val = new Value();
        v = val;
        System.out.println(v.i + " " + i);
    }
}

class Value{
    int i = 15;
}
//值传递例题
//定义一个int型的数组:int[] arr = new int[]{12,3,3,34,56,77,432}
//让数组的每个位置上的值去除以首位置的元素,得到的结果,作为该位置上的新值,遍历新的数组

public class ValueTransfer{
    public static void main(String[] args){
        int[] arr = new int[]{12,3,3,34,56,77,432};
        //方式一:倒着除
        for(int i = arr.length;i >= 0;i--){
            arr[i] = arr[i] / arr[0];
        }

        //方式二:将arr[0]赋值给一个新变量,每个元素除这个不变的变量
        int temp = arr[0];
        for(int i = arr.length;i >= 0;i--){
            arr[i] = arr[i] / arr[0];
        }
    }
}

🇺🇳        递归方法

递归(recursion)方法

        > 递归方法:一个方法体内调用它自身

                > 方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制

                > 递归一定要向已知方向递归,否者这种递归就变成了无穷递归,类似于死循环

//例题1:
//计算1-100以内所有自然数的和
public class RucursionTest{
    public static void main(String[] args){
        //方式一:
        int sum = 0;
        for(int i = 1;i <= 100;i++){
            sum += i
        }
        System.out.println("1-100以内所有自然数的和为:" + sum);

        //方式二:
        RucursionTest test = new RucursionTest();
        int sum1 = test.getSum(100);
        System.out.println("1-100以内所有自然数的和为:" + sum1);
    }
    public int getSum(int n){
        if(n == 1){
            return 1;
        }else{
            return n + getSum(n - 1);
        }
    }
}
//例题2:
//计算1-100以内所有自然数的乘积
public class RucursionTest{
    public static void main(String[] args){
        //方式一:
        int sum = 0;
        for(int i = 1;i <= 100;i++){
            sum *= i
        }
        System.out.println("1-100以内所有自然数的乘积为:" + sum);

        //方式二:
        RucursionTest test = new RucursionTest();
        int sum1 = test.getSumTimes(100);
        System.out.println("1-100以内所有自然数的乘积为:" + sum1);
    }

    public int getSumTimes(int n){
        if(n == 1){
            return 1;
        }else{
            return n * getSumTimes(n - 1);
        }
    }
}
//例题3:
//已知有一个数列:f(0) = 1,f(1) = 4,f(n + 2) = 2 * f(n + 1) + f(n),其中n是大于0的整数,求f(10)的值
public class RucursionTest{
    public static void main(String[] args){
        RucursionTest test = new RucursionTest();
        int num = test.num(10);
        System.out.println(num);
    }

    public int num(int n){
        if(n == 0){
            return 1;
        }else if(n == 1){
            return 4;
        }else{
            return 2 * num(n - 1) + num(n - 2);
        }
    }
}
//例题4:
//斐波那契数列:
//输入一个数据n,计算斐波那契数列(Fibonacci)的第n个值
//1 1 2 3 5 8 13 21 34 55
//规律:一个数等于前两个数的和
//要求:计算斐波那契数列的第n个值,并将整个数列打印出来
public class RucursionTest{
    public static void main(String[] args){
        RucursionTest test = new RucursionTest();
        int fibonacci = test.fibonacci(10);
        System.out.println(fibonacci);
    }

    public int fibulacci(int n){
        if(n <= 0){
            return 0;
        }else if(n == 1){
            return 1;
        }else if(n == 3){
            return 2;
        }else{
            return fibonacci(n - 1) + fibonacci(n - 2);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值