2.6方法

#王者杯·14天创作挑战营·第1期#

 方法是一组执行特定任务的语句集合,它把代码封装起来,能被重复调用,以此提升代码的复用性和可维护性。在 Java 里,方法是类的一部分,定义在类内部。Java 方法需要通过类的对象或者类名(静态方法)来调用。

方法的定义

Java 方法的基本定义格式如下:

修饰符 返回值类型 方法名(参数列表) {
    // 方法体
    return 返回值; // 如果返回值类型不为 void,则必须有返回语句
}

  • 修饰符:像 publicprivateprotected 等访问修饰符,还有 staticfinal 等非访问修饰符,用来控制方法的访问权限和行为。
  • 返回值类型:表明方法执行后返回结果的类型,若方法不返回任何值,返回值类型为 void
  • 方法名:是用于标识方法的名称,要遵循 Java 的命名规范。
  • 参数列表:是传递给方法的参数集合,多个参数之间用逗号分隔。
  • 方法体:包含了实现方法功能的具体代码。
  • 返回值:如果返回值类型不是 void,方法必须使用 return 语句返回一个与返回值类型相符的值。

方法的调用

在 Java 中,调用方法就是执行该方法的代码。若方法是静态方法,可通过类名直接调用;若为非静态方法,则需先创建类的对象,再通过对象调用。

方法的参数

参数分为形式参数(形参)和实际参数(实参)。形参是方法定义时的参数,用于接收调用方法时传递的值;实参则是调用方法时实际传递给方法的值。

方法的返回值

返回值是方法执行完毕后返回给调用者的结果。返回值类型必须与方法定义时指定的返回值类型一致。

示例代码

public class MethodExample {

    // 静态方法,用于计算两个整数的和
    public static int add(int a, int b) {
        return a + b;
    }

    // 非静态方法,用于打印消息
    public void printMessage(String message) {
        System.out.println(message);
    }

    public static void main(String[] args) {
        // 调用静态方法
        int result = add(3, 5);
        System.out.println("3 + 5 = " + result);
/*
在同一个类中调用类方法
当类方法在定义它的类内部被调用时,类前缀能够省略。
这是由于在类的内部,编译器能够明确知晓该方法属于哪个类。
*/

        // 创建对象
        MethodExample example = new MethodExample();
        // 调用非静态方法
        example.printMessage("Hello, Java!");
    }
}

代码解释

  • add 方法属于静态方法,可直接通过类名调用。它接收两个整数参数,返回它们的和。
  • printMessage 方法是非静态方法,要先创建 MethodExample 类的对象,再通过对象调用。它接收一个字符串参数,把该字符串打印输出。
  • 在 main 方法里,先调用 add 方法计算两个整数的和并输出结果,接着创建 MethodExample 类的对象,调用 printMessage 方法打印消息。
  • 属于类:类方法属于类本身,而不属于类的某个实例。无论创建多少个类的实例,类方法都只有一份。
  • 可直接访问:可以直接通过类名调用,无需创建类的实例。
  • 访问限制:类方法只能访问类的静态成员(静态变量和静态方法),不能直接访问实例变量和实例方法。这是因为实例变量和实例方法是依赖于具体的对象实例的,而类方法在调用时可能还没有创建对象。

静态方法使用场景

  • 工具类方法:当方法不需要访问对象的状态,只需要进行一些通用的计算或操作时,可以将其定义为静态方法。例如,Java 中的 Math 类,它包含了很多静态方法,如 Math.sqrt() 用于计算平方根,Math.random() 用于生成随机数等。
  • 工厂方法:用于创建类的对象,特别是在创建对象的过程比较复杂,或者需要根据不同的条件创建不同类型的对象时。

对象方法的使用场景

对象方法可以用来实现对象所具有的特定行为,这些行为与对象的属性和功能相关。对象方法可以将相关的业务逻辑封装在对象内部,提高代码的可维护性和可复用性。

方法的重载

在 Java 中,方法重载指的是在同一个类里可以定义多个同名方法,但这些方法的参数列表不同(参数的类型、个数或顺序不同)。方法重载能让代码更具可读性和易用性。示例如下:

public class MethodOverloadingExample {

    // 计算两个整数的和
    public static int add(int a, int b) {
        return a + b;
    }

    // 计算三个整数的和
    public static int add(int a, int b, int c) {
        return a + b + c;
    }

    // 计算两个双精度浮点数的和
    public static double add(double a, double b) {
        return a + b;
    }

    public static void main(String[] args) {
        System.out.println("2 + 3 = " + add(2, 3));
        System.out.println("2 + 3 + 4 = " + add(2, 3, 4));
        System.out.println("2.5 + 3.5 = " + add(2.5, 3.5));
    }
}

在这个示例中,add 方法被重载了三次,分别用于计算两个整数的和、三个整数的和以及两个双精度浮点数的和。在调用 add 方法时,Java 编译器会依据传递的参数类型和个数自动选择合适的方法。

Java ​​只有值传递​​。所有参数传递的本质都是传递值的副本​

  • 当传递引用类型时,传递的是引用的副本,而非原始引用本身。
  • 方法内无法直接修改外部的基本类型变量。
  • 方法内可以通过引用的副本修改对象的内容,但无法改变外部引用指向的对象。

  • ​示例代码​​:

    public class ValuePassingDemo {
        public static void main(String[] args) {
            int num = 10;
            modifyPrimitive(num);
            System.out.println(num); // 输出 10(未被修改)
        }
    
        public static void modifyPrimitive(int x) {
            x = 20; // 修改的是副本,不影响原始变量
        }
    }

    num 的值 10 被复制到参数 x 中。方法内修改 x 不会影响外部的 num

  • 传递引用的副本

    ​示例 1:修改数组内容(生效)​

    
    public class ReferencePassingDemo {
        public static void main(String[] args) {
            int[] numbers = {10, 20, 30};
            modifyNumber(numbers);
            System.out.println( Arrays.toString(numbers));
        }
    
        public static void modifyNumber(int[] n) {
                    // Modify the first element of the array
                    n[0] = 99;
        }
    }

    numbers的引用值(内存地址)被复制到参数 n 中。

    numbers 和 n 指向同一个对象,因此修改 n[0] 会影响原对象。
  •  示例 2:试图修改引用指向的对象(无效)​
public class ReferencePassingDemo {
    public static void main(String[] args) {
        int[] numbers = {10, 20, 30};
        modifyNumber(numbers);
        System.out.println( Arrays.toString(numbers));
    }

    public static void modifyNumber(int[] n) {
                // Modify the n to a new array
                n = new int[]{1,2,4};
    }
}
  • 参数 n 是 numbers 引用值的的副本。
  • 在方法内让 n 指向新对象,但外部的 numbers 仍指向原对象。

方法设计的技巧

单一职责原则

一个方法应该只负责一项明确的任务。这样可以使方法的功能更加清晰,易于理解和维护。如果一个方法承担了过多的职责,当其中一个职责需要修改时,可能会影响到其他职责,增加代码出错的风险。

  • 参数数量:尽量减少方法的参数数量,过多的参数会使方法调用变得复杂,也增加了出错的可能性。如果需要传递多个参数,可以考虑将相关的参数封装成一个对象。
  • 明确返回值类型:方法的返回值类型应该与方法的功能相匹配。如果方法不返回任何有意义的值,应该使用 void 类型。
  • 不依赖对象状态:当方法不需要访问对象的实例变量,只进行一些通用的计算或操作时,适合使用静态方法。
  • 实现对象行为:如果方法是实现对象所具有的特定行为,这些行为与对象的属性和功能相关,通常使用实例方法。

综合案例: 

根据输入的数字打印出对应的等腰三角形。在这个程序中,输入的数字表示等腰三角形的行数。


import java.util.Scanner;

public class TrianglePrint {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入一个正整数,表示三角形的行数: ");
        int n = scanner.nextInt();
        scanner.close();
        printTriangle(n);        
    }

    // 打印等腰三角形的方法
    public static void printTriangle(int n) {
        for (int i = 1; i <= n; i++) {
            // 打印空格
            for (int j = n - i; j > 0; j--) {
                System.out.print(" ");
            }
            // 打印星号
            for (int k = 0; k < 2 * i - 1; k++) {
                System.out.print("*");
            }
            System.out.println();
        }
    }
}

打印乘法表

    public static void multiplicationTabl {
        for (int i = 1; i <= 9; i++) {
            for (int j = 1; j <= i; j++) {
                System.out.print(j + "×" + i + "=" + i * j + "\t");
            }
            System.out.println();
        }
    }

生成双色球

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Random r = new Random();
        int[] reds = getRedBalls();
        bubbleSort(reds);

        // 输出红色球号码
        System.out.print("红色球号码: ");
        for (int redBall : reds) {
            System.out.printf("%02d ", redBall);
        }
        // 输出蓝色球号码

        System.out.print("\n蓝色球号码: ");
        System.out.printf("%02d\n", r.nextInt(16) + 1);
    }

    // 生成 6 个不重复的红色球号码
    public static int[] getRedBalls() {
        int[] reds = new int[33];
        for (int i = 0; i < reds.length; i++) {
            reds[i] = i+1;
        }
        Random r = new Random();
        //洗牌算法,把数组打乱
        for (int i =  reds.length -1 ; i > 0; i--) {
            //i 从32.也随时数组的最后一位。开始和随机生成的位置交换。
            int tmp = r.nextInt(i+1); //随机数 从0 到 32(需要包含32)所以要加1
            if (tmp == i){
                //如果随机数和要交换的数字相等。则不换位置
            }else{
                int tmpInt  = reds[i];
                reds[i] = reds[tmp];
                reds[tmp] = tmpInt;
            }
        }
        //返回乱序数组的前六个
        return Arrays.copyOf(reds,6);
    }

    // 冒泡排序,对int数组进行排序
    public static void bubbleSort(int[] arr) {
        int n = arr.length;
        for (int i = 0; i < n - 1; i++) {
            for (int j = 0; j < n - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    // 交换 arr[j+1] 和 arr[j]
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

chxii

小小打赏,大大鼓励!

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

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

打赏作者

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

抵扣说明:

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

余额充值