第9篇:Java 成员方法详解

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

一、成员方法简单使用

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

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

在这里插入图片描述

public class Person {
    private String name;

    /**
     * 做自我介绍(成员方法)
     */
    public void selfIntroduce() {
        System.out.println("你好, 我叫杨嘉立。杨树的杨, 嘉奖的嘉, 立正的立。");
    }

}
public class Main {

    public static void main(String[] args) {
        Person person = new Person();
        // 你好, 我叫杨嘉立。杨树的杨, 嘉奖的嘉, 立正的立
        person.selfIntroduce();
    }

}

创建 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;
    }

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

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

二、方法的调用机制

在前面的文章中博主分享过对象的内存布局和栈帧等概念,不知道的童鞋去看看吧
通过下面的代码分析方法的调用机制:

public class Person {

    /**
     * 计算两个整数的和
     */
    public int sumOfTwo(int n1, int n2) {
        return n1 + n2;
    }

}
public class Main {

    public static void main(String[] args) {
        Person person = new Person();

        // 520
        System.out.println(person.sumOfTwo(500, 20));
    }

}

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

三、成员方法的好处

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

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

打印下面的二维数组:
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();
        }
    }

}
🍀上面的代码,把打印二维数组的代码复制了三份,从而实现【打印二维数组】功能重复使用。但若是需要修改代码实现逻辑的话,则需要修改三处,这很不高效。
🍀 类的成员方法的实现逻辑被存放在 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);
    }

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

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

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

}
🌠 引用类型传参是引用(地址值)传递(通过地址值可以修改引用类型的值)
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);
    }
}
❄️ 引用类型传参的时候,形参的改变会影响实参
❄️ 方法返回值是引用类型,实际返回的是对象的地址值
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;
}

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

相关文章
|
3月前
|
存储 Java
java成员变量详解
java成员变量详解
|
4月前
|
存储 Java
Java成员变量详解
Java成员变量详解
83 0
|
4月前
|
存储 Java 数据安全/隐私保护
Java成员方法深入解析
Java成员方法深入解析
53 0
|
Java
Java final关键字详解
1.final 2.final修饰变量 (1)final修饰局部变量 (2)final修饰成员变量 3.final修饰方法
62 0
|
4月前
|
Java
Java中的super关键字
Java中的super关键字
42 0
|
Java
java final关键字 详解
java final关键字 内容分享,本篇博文为java 面向对象三大特性——多态篇的补充。
84 0
java final关键字 详解
|
Java
java super关键字详解
1.super介绍 我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。 用于访问父类的属性,方法,构造器 2.super的基本使用 我们来演示以下子类调用父类的属性,方法和构造器 父类:
116 0
java super关键字详解
|
Java
Java中的成员方法的使用
Java中的成员方法的使用
140 0
Java中的成员方法的使用
|
Java
Java中静态方法的使用
Java中静态方法的使用
132 0
Java中静态方法的使用
|
Java
Java中的权限修饰符
Java中的权限修饰符
83 0
Java中的权限修饰符