JavaSEDemo05

本文探讨了Java编程中的void方法使用规范,可变与不可变API的区别,数据交换的正确方式,方法重载的判断依据,以及构造方法的使用和调用。此外,还讲解了this关键字在链式编程中的应用,构造方法调用同名构造方法的规则,以及方法递归的示例。通过实例解析了如何解决猴子吃桃问题,展示了递归的应用。
摘要由CSDN通过智能技术生成

简介

  • 本文是2021/03/24晚上整理的笔记
  • 赘述可能有点多,还请各位朋友耐心阅读
  • 本人的内容和答案不一定是最好最正确的,欢迎各位朋友评论区指正改进。

void方法中return语句的使用规范

  • void方法一般是不写return语句的,当然了也可以写。
  • void方法中return语句的使用规范:(1)return后面什么也不跟;(2)return必须是最后一句。
  • (1)如果我们在return语句后写了数值
  • 代码示例:
public static void method(){
        return null;
    }

  • 在这里插入图片描述
  • 错误解释 无法从返回值类型为void方法中返回一个值
  • (2)如果我们在return语句后写了语句
    public static void method(){
        return;
        System.out.println();
    }

  • 在这里插入图片描述
  • 解释:无法到达的语句;

可变API与不可变API

  • 可变API:在给定的既有内存上进行操作的API
  • 不可变API:执行时需要分配新的内存才能执行的API,new关键字创建对象时就是不可变API,它为对象分配新的空间。
  • 其中,最常见的,Java的String类型没有任何的可变API,因为你对字符串的任何改变都只是创建了一个新的字符串对象。

数据交换与方法传参

public class Test {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        swap(a,b);
        System.out.println("main方法中a:"+a+" b:"+b);
    }
    public static void swap(int a,int b){
        int temp = a;
        a = b;
        b = temp;
        System.out.println("swap方法中a:"+a+" b:"+b);
    }
}

程序运行结果

swap方法中a:20 b:10
main方法中a:10 b:20
  • 为什么main方法中的a和b值没有发生交换呢?
  • 因为Java使用的是值传递,值传递是将传入方法的实参拷贝一份交给形参,并不会对原实参产生影响。
  • 关于值传递和引用传递我在另一篇博客里有写,感兴趣的可以点击跳转
    2021/03/21Java中向方法中传入参数时遇到的问题
  • 请看内存图
    在这里插入图片描述
  • 那么如何交换数据呢?我们可以使用类对数据进行包装(注意和包装类不是一个东西)
  • 注意:本处代码中的User类和Test分别在两个java文件中
//定义一个User类
public class User {
    int a = 10;
    int b = 20;
}
---------------------------------------------------
//测试类
public class Test {
    public static void main(String[] args) {
        User user = new User();
        swap(user);
        System.out.println("main方法中a:"+user.a+" b:"+user.b);
    }
    public static void swap(User user){
        int temp = user.a;
        user.a = user.b;
        user.b = temp;
        System.out.println("swap方法中a:"+user.a+" b:"+user.b);
    }
}

程序运行结果

swap方法中a:20 b:10
main方法中a:20 b:10
  • 为什么用类对数据包装完以后,就可以实现数据交换了呢?
  • 因为我们创建一个对象的时候,Java会为对象在堆中分配内存,我们通过对象访问堆中存储的成员变量,swap方法传入的参数是对象在堆中的地址,交换的数据也是堆中的变量。
  • 请看内存图
    在这里插入图片描述

为什么不能用返回值类型来判断方法是否重载

    public void add(double a,double b){

    }
    public double add(double a,double b){
        double sum = a + b;
        return sum;
    }
  • 假如我们定义了两个方法名称相同,参数列表相同,返回值类型不同的方法。(如上代码是错误的)
  • 如果我们想要调用有返回值的方法,编译器却为我们调用了没有返回值类型的方法。那岂不是闹了笑话?
  • 编译器傻傻分不清楚

可变参数

    public static void show(int a,int...b){
    }
  • 如上代码:int…b就是一个可变参数
  • 无论你之后传入多少参数都可以接收
  • 使用规范:
  • (1)可变参数只能有一个
  • (2)可变参数必须写在参数列表的最后一个
  • (3)书写格式:数据类型…形参名称 三个点和前后的数据类型和形参名称中间有没有空格都可以
  • (4)可变参数与数组类似,也有长度:参数名称.length
public class Test {
    public static void main(String[] args) {
        System.out.println(show(1,2,3,4,5,6,7));
    }
    public static int show(int...a){
         return a.length;
    }
}

程序运行结果

7

普通方法与构造方法同名

  • 在Java中允许普通方法与构造方法同名,但是不推荐这么写
public class User {
    String name;
    int age;
    //无参构造方法
    public User() {
        System.out.println("无参构造方法被调用");
    }
    //全参构造方法
    public User(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("全参构造方法被调用");
    }
    //普通方法
    void User(){
        System.out.println("普通方法被调用");
    }
}
---------------------------------------------------
public class Test {
    public static void main(String[] args) {
        User u1 = new User();
        User u2 = new User("张三",20);
    }
}

程序运行结果

无参构造方法被调用
全参构造方法被调用
  • 我们创建对象时只会调用构造方法,若想调用普通方法,创建好对象后,通过对象名.方法名来调用。

构造方法调用同名构造方法

public class User {
    int number;
    int age;
    //全参构造方法
    public User(int number, int age) {
        this.number = number;
        this.age = age;
    }
    //无参构造方法
    public User() {
        this(0,0);
    }
}
  • 如上代码,无参构造方法中调用了全参构造方法,实参为0和0
  • 构造方法调用同名构造方法的使用规范:this语句必须为第一句
  • 否则会出现以下错误:
    在这里插入图片描述
    错误解释:调用this()必须时构造方法中第一条语句。

this与链式编程

  • 我们用一段代码来演示链式编程的效果
//苹果类
public class Apple {
    int apple = 0;
    //返回值类型为本类Apple类,返回this,即返回调用此方法的对象,调用时可以连续调用。
    public Apple addApple(){
           apple++;
           return this;
    }
    //打印苹果的数量
    public void print(){
        System.out.println("共有苹果:"+apple+"个");
    }
}
-----------------------------------
//测试类
public class Test {
    public static void main(String[] args) {
        Apple apple = new Apple();
        //一共调用了3次addApple方法,apple增加了3次
        apple.addApple().addApple().addApple().print();
    }
}

程序运行结果

共有苹果:3

this用于传递本对象引用

/* 定义父亲类和儿子类,父亲可以采摘苹果,儿子也可以采摘苹果
*/
public class Son {
       //定义苹果数量
      int apple;
      //定义一个儿子类中的摘苹果的方法
      public void pickApple(){
      //此方法中创建了一个Father类对象
         Father father = new Father();
         //将调用此方法的对象,传给父亲类中的摘苹果的方法
         father.pickApple(this);
      }


}
--------------------------------
public class Father {
       //定义一个父亲类中的摘苹果的方法,参数为Son类型的对象
    public void pickApple(Son son){
          son.apple = 50;
    }
    //main方法
    public static void main(String[] args) {
        Son son = new Son();
        son.pickApple();
        System.out.println(son.apple);
    }
}

程序运行结果

50

看上去比较乱,我们来看一下内存图
在这里插入图片描述

java的访问修饰符

在这里插入图片描述

构造方法的特点

  • 语法:public 类名(){
    }
  • 构造方法没有返回值

方法签名

  • 由方法名称和参数列表组成。方法签名常用于方法重载和重写。

方法递归及练习

  • 方法自己调用自己
  • 方法递归要有一个明确的方向,不然程序会一直进行下去,形成死循环
  • 练习题目:
    有一只猴子摘了一大堆桃子吃,它按照这样的规律吃桃子:第一天吃一半多一个,第二天吃第一天剩余的一半多一个,第三天吃第二天剩余的一半多一个…以此类推,当第七天时,恰好只剩下一个桃子。求猴子一共摘了多少个桃子?
  • 解题思路:我们可以用数学思想来解决这个问题
  • 设一个F(n),F为桃子数量 n为天数
  • 我们知道F(7)=1,第七天是第六天吃剩下的,第六天吃了一半多一个
  • 即F(7)=F(6)-F(6)/2 -1 ;
  • 换算一下,就得出 F(6) = [F(7)+1] x 2
  • 继续可以得出 F(5) = [F(6)+1] X 2
  • F(4) = [F(5)+1] X 2
  • 规律就是 F(n) = [F(n+1) + 1] X 2
  • 同时递归的终止条件为F(7) =1
  • 代码实现:
public class Monkey {
    public static void main(String[] args) {
        System.out.println("最初有"+F(1)+"个桃子");
    }
    public static int F(int n){
               if(n ==7){
                   return 1;
               }else{
                   return (F(n+1)+1)*2;
               }
    }
}

程序运行结果

最初有190个桃子
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

香鱼嫩虾

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

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

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

打赏作者

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

抵扣说明:

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

余额充值