• 9、Java 成员方法详解


    一、成员方法简单使用

    ⛄️ 在【官方教程解释类和对象】这篇文章中说到:就像现实世界的对象中有状态行为一样,Java 编程中的对象也有【行为】,在 Java 编程中对象的行为被叫做【成员方法(简称方法)】

    需求:创建 Person 类,提供【做自我介绍】的方法

    在这里插入图片描述

    public class Person {
        private String name;
    
        /**
         * 做自我介绍(成员方法)
         */
        public void selfIntroduce() {
            System.out.println("你好, 我叫杨嘉立。杨树的杨, 嘉奖的嘉, 立正的立。");
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    public class Main {
    
        public static void main(String[] args) {
            Person person = new Person();
            // 你好, 我叫杨嘉立。杨树的杨, 嘉奖的嘉, 立正的立
            person.selfIntroduce();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    创建 Calculator 类, 提供以下3个方法:
    (1) 计算 [1, 100] 的累加和
    (2) 计算 [start, end] 的累加和
    (3) 计算任意个整数的累加和

    /**
     * 计算类(用于做各种计算)
     */
    public class Calculator {
    
        /**
         * 计算 [1, 100] 的累加和
         */
        public int sumOne2Hundred() {
            int start = 1;
            int end = 100;
            int sum = 0;
            for (int i = start; i <= end; i++) {
                sum += i;
            }
            return sum;
        }
    
        /**
         * 计算 [start, end] 的累加和
         */
        public int sumStart2End(int start, int end) {
            int sum = 0;
            for (int i = start; i <= end; i++) {
                sum += i;
            }
            return sum;
        }
    
        /**
         * 计算提供的多个整数的累加和
         *
         * @param ints 提供的多个整数
         * @return 累加和
         */
        public int sumGivenInt(int... ints) {
            int sum = 0;
            for (int i = 0; i < ints.length; i++) {
                sum += ints[i];
            }
            return sum;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    public class Main {
    
        public static void main(String[] args) {
            Calculator calculator = new Calculator();
    
            // [1, 100] 累加和: 5050
            System.out.println("[1, 100] 累加和: " + calculator.sumOne2Hundred());
    
            // [1, 1000] 累加和: 500500
            System.out.println("[1, 1000] 累加和: " + calculator.sumStart2End(1, 1000));
    
            // 任意多个整数累加: 979
            System.out.println("任意多个整数累加: " + calculator.sumGivenInt(66, 888, 25));
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    Person 和 Calculator 两个类中一共定义了 4 个方法:
    ❄️ public void selfIntroduce()
    ❄️ public int sumOne2Hundred()
    ❄️ public int sumStart2End(int start, int end)
    ❄️ public int sumGivenInt(int... ints)
    💐 四个方法定义的最前面都有 public,它是访问修饰符(限制方法可以被访问的范围)。public 表示公共的,可访问范围最广。访问修饰符共有四个:① public、② protected、③ default、④ private
    💐 第一个方法(selfIntroduce)的 void 表示该方法没有返回值,而其他方法都有返回值(返回值类型是 int)
    💐 第一和第二个方法(selfIntroduce 和 sumOne2Hundred)都没有方法参数;sumStart2End 方法有2个方法参数,sumGivenInt 方法的方法参数是未知的(可能没有、可能1个、可能两个 …)

    二、方法的调用机制

    在前面的文章中博主分享过对象的内存布局和栈帧等概念,不知道的童鞋去看看吧,顺便支持一下博主:http://t.csdn.cn/moZa3
    通过下面的代码分析方法的调用机制:

    public class Person {
    
        /**
         * 计算两个整数的和
         */
        public int sumOfTwo(int n1, int n2) {
            return n1 + n2;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    public class Main {
    
        public static void main(String[] args) {
            Person person = new Person();
    
            // 520
            System.out.println(person.sumOfTwo(500, 20));
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述
    在这里插入图片描述

    三、成员方法的好处

    🍀 提高代码的复用性(不用重复编写相同的代码)
    🍀 将实现的细节封装起来,其他工程师调用方法即可,无需知道底层实现细节

    成员方法提高代码复用性的代码体现:

    打印下面的二维数组:
    int[][] twoArray = {{5, 2, 0}, {6, 7, 8}, {1, 3, 9}};

    public class MemberMethodAdvantage {
    
        public static void main(String[] args) {
            int[][] twoArray = {{5, 2, 0}, {6, 7, 8}, {1, 3, 9}};
            // 1. 打印 twoArray 数组
            System.out.print("\n");
            for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 3; j++) {
                    System.out.print(" " + twoArray[i][j]);
                }
                System.out.println();
            }
    
            System.out.println();
            for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 3; j++) {
                    System.out.print(" " + twoArray[i][j]);
                }
                System.out.println();
            }
    
            System.out.println();
            for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 3; j++) {
                    System.out.print(" " + twoArray[i][j]);
                }
                System.out.println();
            }
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    🍀上面的代码,把打印二维数组的代码复制了三份,从而实现【打印二维数组】功能重复使用。但若是需要修改代码实现逻辑的话,则需要修改三处,这很不高效。
    🍀 类的成员方法的实现逻辑被存放在 jvm 的方法区(且每个类的成员方法只在方法区保存一份),每个该类的对象都可调用方法区的成员方法,即使有一千个对象,成员方法也只有一个,真正是实现了代码的复用。

    四、方法传参机制

    看下面的代码,思考打印的值是什么?

    public class ArgumentsPassingTest {
    
        public static void main(String[] args) {
            ArgumentsPassingTest passing = new ArgumentsPassingTest();
            int a = 66;
            int b = 88;
            passing.swap(a, b);
            // main の a = 66
            System.out.println("main の a = " + a);
            // main の b = 88
            System.out.println("main の b = " + b);
        }
    
        public void swap(int a, int b) {
            int temp = a; // temp = 66
            a = b; // a = 88
            b = temp; // b = 66
            // a = 88
            System.out.println("a = " + a);
            // b = 66
            System.out.println("b = " + b);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    🌠 基本数据类型传参是【值】传递
    🌠 形参的任何改变不会影响实参

    看下面的代码,思考打印的值是什么?

    public class ArgumentsPassingTest {
    
        public static void main(String[] args) {
            int[] nums = new int[]{1, 2, 3};
            ArgumentsPassingTest test = new ArgumentsPassingTest();
    
            // call test 之前: nums = [1, 2, 3]
            System.out.println("call test 之前: nums = " + Arrays.toString(nums));
            test.arrTest(nums);
            // call test 之后: nums = [1, 5, 3]
            System.out.println("call test 之后: nums = " + Arrays.toString(nums));
        }
    
        private void arrTest(int[] nums) {
            nums[1] = nums[1] * 2 + 1;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    🌠 引用类型传参是引用(地址值)传递(通过地址值可以修改引用类型的值)

    public class ArgumentsPassingTest {
    
        public static void main(String[] args) {
            ArgumentsPassingTest test = new ArgumentsPassingTest();
    
            Handsome handsome = new Handsome();
            // 1: 鹿晗
            System.out.println("1: " + handsome.name);
    
            test.handsomeTest2(handsome);
            // 2: 周杰伦
            System.out.println("2: " + handsome.name);
    
            test.handsomeTest1(handsome);
            // 3: 王俊凯
            System.out.println("3: " + handsome.name);
    
            test.handsomeTest3(handsome);
            // 4: 壹诺
            System.out.println("4: " + handsome.name);
    
            test.handsomeTest4(handsome);
            // 5: 潘忠举
            System.out.println("5: " + handsome.name);
    
            // Handsome.name = 潘忠举
            handsome.printName();
    
        }
    
        private void handsomeTest1(Handsome handsome1) {
            handsome1.name = "王俊凯";
        }
    
        private void handsomeTest2(Handsome handsome2) {
            handsome2.name = "周杰伦";
        }
    
        private void handsomeTest3(Handsome handsome3) {
            handsome3.name = "壹诺";
        }
    
        private void handsomeTest4(Handsome handsome3) {
            handsome3.name = "潘忠举";
        }
    
    }
    
    class Handsome {
        String name = "鹿晗";
    
        void printName() {
            System.out.println("Handsome.name = " + name);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    ❄️ 引用类型传参的时候,形参的改变会影响实参
    ❄️ 方法返回值是引用类型,实际返回的是对象的地址值

    public class ArgumentsPassingTest {
    
        public static void main(String[] args) {
            Flower flower = new Flower();
            flower.name = "兰花";
            flower.price = 61;
    
            // flower.name = 兰花
            System.out.println("flower.name = " + flower.name);
            // flower.price = 61
            System.out.println("flower.price = " + flower.price);
    
            Flower copyFlower = copyFlower(flower);
            // copyFlower.name = 兰花
            System.out.println("copyFlower.name = " + copyFlower.name);
            // copyFlower.price = 61
            System.out.println("copyFlower.price = " + copyFlower.price);
    
            // false【false 表示 flower 和 copyFlower 不是同一个对象】
            System.out.println(flower == copyFlower);
        }
    
        private static Flower copyFlower(Flower flower) {
            Flower flowerCopy = new Flower();
            flowerCopy.name = flower.name;
            flowerCopy.price = flower.price;
            return flowerCopy;
        }
    
    }
    
    class Flower {
        String name;
        int price;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    好困啊,今天就写到这儿吧!

  • 相关阅读:
    通过SSH 可以访问Ubuntu Desktop吗?
    SAP-MM-错误代码M7018 输入物料转移过账
    策略模式demo
    js的作用域
    Ts中的Pick,Omit,Extract和Exclude区别
    6月25日PMP考试敏捷怎么考?替你分忧解难
    四川云汇优想:短视频矩阵运营方案
    【解决方案】智慧体育场馆大场景安防视频监控,可持续性保障大型场馆安全运行
    营业执照的五大误区,企业千万不要踩雷
    react 组件间的通信
  • 原文地址:https://blog.csdn.net/m0_54189068/article/details/126656744