JAVA 方法


目录

  • 方法
    • 一、方法的调用机制
    • 二、成员方法
      • 2.1成员方法的定义
      • 2.2注意事项和细节
    • 三、方法练习题
    • 四、成员方法传参机制
      • 4.1基本数据类型的传参机制
      • 4.2引用数据类型

方法

概念:在某些情况下,我们要需要定义成员方法(简称方法)。比如人类:除了有一些属性外( 年龄,姓名..),我们人类还有一 些行为比如:可以说话、跑步..,通过学习,还可以做算术题。这时就要用成员方法才能完成。

一、方法的调用机制

  1. 当程序执行到方法时,就回开辟一个独立的空间(空间)
  2. 当方法执行完毕,或者执行到return语句时,就回返回
  3. 返回到调用的地方
  4. 返回后,继续执行方法后面的代码
  5. main方法(栈),执行完毕,整个程序就退出

image-20220113174300167


二、成员方法

为什么需要成员方法

  1. 提高了代码的复用性,减少了代码的冗余
  2. 可以将实现的细节封装起来,供其他用户使用
    • 利于开发,提高开发效率

例如:

题目:请遍历一个数组 , 输出数组的各个元素

package Method_Practice;

public class Method02 {
        public static void main(String[] args) {
            int map[][] = {{0,0,1},{1,1,1},{1,1,3}} ;
            
            //创建MyTool 类
            MyTools tool = new MyTools();
            //二维数组的遍历
            tool.arrPrintf(map);
        }
}

//定义一个工具类,写入方法,在主函数中进行调用实现遍历
class MyTools{

    //编写方法,接受二维数组,并进行相关处理
    public void arrPrintf(int map[][]) {
        //方法体:为了完成数据遍历的功能
        System.out.println("=====");
        for (int i = 0; i < map.length; i++) {
            for (int j = 0; j < map[i].length; j++) {
                System.out.print(map[i][j] + " ");
            }
            System.out.println();
        }
    }
}

2.1成员方法的定义

    访问修饰符 返回数据类型 方法名(新参列表) {    
        语句;
        return 返回值;
    }
  1. 形参列表:表示成员方法的输入
  2. 返回数据类型:表示成员方法输出, void 表示没有
  3. 方法主体:表示为了实现某一功能代码块
  4. return 语句不是必须的,当有个具体的返回数据类型时,就必须要有个return 语句

2.2注意事项和细节

访问修饰符

作用:是控制方法使用的范围

  • 如果不写默认访问
    • public 表示方法公开
    • protected
    • 默认
    • private

返回数据类型

  1. 一个方法最多有一个返回值
    • 思考:如果要返回多个返回值
      • 可以返回数组
  2. 返回类型可以为任意类型,包含基本类型或引用类型(数组,对象)
  3. 如果方法要求有返回数据类型,则方法体中最后的执行语句必须为 return 值; 而且要求返回值类型必须和 return 的 值类型一致或兼容
    • 没有办法把高精度的转换成低精度的
  4. 如果方法是 void,则方法体中可以没有 return 语句,或者 只写 return

方法名

在实际工作中,我们的方法都是为了完成某个功能,所以方法名一定要有某个含义

  • 遵循驼峰命名法,最好见名知义,表达出该功能的意思即可, 比如 得到两个数的和 getSum, 开发中按照规

形参列表

  1. 一个方法可以有0个参数,也可以有多个参数,中间用逗号隔开
  2. 参数类型可以是任意类型
  3. 调用带参数的方法时,一定对应着参数列表传入相同类型或兼容的类型
  4. 方法定义的时候称为形参,简称形参;方法调用时用的参数为实际参数,简称实参,实参和形参的类型要一致或兼容、个数、顺序必须一致!

方法体

方法体不能嵌套定义,但是可以使用方法

方法调用

  1. 同一个类中的方法调用:直接调用即可

  2. 跨类中的方法A类调用B类方法:需要通过对象名调用

    • 比如 对象名.方面名(参数);

      class AA{
          //1.返回值能返回任意类型,这里是返回的数组
          //在同一个类中的方法:直接调用即可
         public int[] getSumAndSub( int num1,int num2) {
             int retArr[] = new int[2];
             retArr[0] = num1 + num2;
             retArr[1] = num1 - num2;
      
             printArr(retArr);
             System.out.println("\n返回了,继续执行getSumAndSub");
             return retArr;
         }
      
         public void printArr(int res[]) {
             for(int i = 0 ; i < res.length ; i++) {
                 System.out.print(res[i] + " ");
             }
         }
      
         //跨类调用
         public void m1() {
             System.out.println("m1方法被调用");
             B b = new B();
             b.hi();
             System.out.println("m1方法继续执行");
         }
      }
      
      
      class B{
      
         public void hi() {
             System.out.println("B类中的hi()方法被执行");
         }
      }
  3. 特别说明:

    • 跨类的方法调用和方法的访问修饰符相关

三、方法练习题

题目:编写类 AA ,有一个方法:判断一个数是奇数 odd 还是偶数, 返回 boolean

题目:根据行、列、字符打印 对应行数和列数的字符,比如:行:4,列:4,字符#,则打印相应的效果

package Method_Practice;

public class MethodExercise {
        public static void main(String[] args) {
            A a = new A();
            int num = 5;
            if(a.isOdd(num)) {
                System.out.println(num+" 是奇数");
            }else {
                System.out.println(num+" 是偶数");
            }
            
            int row = 5;
            int col = 5;
            char ch = '*';
            a.printChar(row, col,ch);
        }
}

//题目:
//编写类 AA ,有一个方法:判断一个数是奇数 odd 还是偶数, 返回 boolean

class A{
    //如果是奇数返回true,不是则返回false    
    public boolean isOdd(int n) {
        /*
         * boolean ret = true; if(n%2 == 0) { ret = false; } return ret;
         */
        return n %2 !=0 ? true:false;
    }
    
//题目:
//根据行、列、字符打印 对应行数和列数的字符,比如:行:4,列:4,字符#,则打印相应的效果
    public void printChar(int row , int col,char ch) {
        System.out.println();
        for (int i = 1; i <= row; i++) {
            for (int j = 1; j <= col; j++) {
                System.out.print(ch + " ");
            }
            System.out.println();
        }
        
    }
}


四、成员方法传参机制

4.1基本数据类型的传参机制

例如:

package Method_Practice;

public class MethodParameter01 {
     public static void main(String[] args) {
        int num1 = 10;
        int num2 = 20;
        BB b = new BB();
        b.swap(num1, num2);
        
        System.out.println("\nmain方法中:");
        System.out.println("a=" + num1 + ",b=" + num2);//a=10,b=20
    }
    
}

class BB{

    public void swap(int a, int b) {
        //完成a和b 的交换
        System.out.println("swap方法中:");
        //交换前
        System.out.println("a和b交换前\na=" + a + ",b=" + b);//a=10,b=20
        int temp = a;
        a = b;
        b = temp;
        //交换后
        System.out.println("\na和b交换后\na=" + a + ",b=" + b);//a=20,b=10
    }
}

结论:

  • 对于基本数据类型,传递的是值(值拷贝),形参的任何改变不会影响实参

4.2引用数据类型

package Method_Practice;

public class MethodParameter02 {
    public static void main(String[] args) {
        AAA myA = new AAA();
        MyPerson p1 = new MyPerson();

        int a[] = {6,9,10,69,98,63,3};
        System.out.println("原数组:");
        myA.printArr(a);
        myA.test100(a);
        System.out.println("调用myA.test100后:");
        myA.printArr(a);
        
        p1.age = 16;
        p1.sal = 60;
        System.out.println("\n原myperson对象的值");
        myA.printPerson(p1);
        
        myA.test200(p1);
        System.out.println("调用myA.test200后:");
        myA.printPerson(p1);
    }
}

class AAA{
    //B类中编写一个方法 test100,
    //可以接收一个数组,在方法中修改该数组,看看原来的数组是否变化?
    public void test100(int a[]) {
        for (int i = 0; i < a.length; i++) {
            a[i] = i;
        }
    }
    
    //B 类中编写一个方法 test200,可以接收一个 Person(age,sal)对象,
    //在方法中修改该对象属性,看看原来的对象是否变
    public void test200(MyPerson p) {
        p.age = 21;
        p.sal = 100.0;
    }
    
    //输出数组
    public void printArr(int b[]) {
        for (int i = 0; i < b.length; i++) {
            if(i == 0) {
                System.out.print("[");
            }
            System.out.print(b[i]);
            if(i != b.length -1) {
                System.out.print(" ");
            }
            
            if(i == b.length-1) {
                System.out.print("]");
            }
        }
        System.out.println();
    }
    
    //输出MyPerson的各个属性
    public void printPerson(MyPerson p1) {
        System.out.println("p1.age=" + p1.age +"\np1.sal=" + p1.sal );
        System.out.println();
    }
    
}

class MyPerson{
    int age;
    double sal;
}

运行效果:

image-20220115111339368

结论:

  • 引用类型传递是地址(地址也是指,但值是地址),可以通过形参的改变来改变实参
    • 对象也是引用类型的,故在方法中修改对象的值,也会修改对象的值
    • 如果对象名相同,但地址不通,则优先调用主在原本的对象的值

内存空间示意图

image-20220115152500980

image-20220115152536085


练习

题目:

编写一个方法 copyPerson,可以复制一个 Person 对象,返回复制的对象。克隆对象, 注意要求得到新对象和原来的 对象是两个独立的对象,只是他们的属性相同

package Method_Practice;

public class MethodExercise01 {
    public static void main(String[] args) {
        Person p1 = new Person();
        MyTools tool = new MyTools();
        p1.name = "小杨";
        p1.age = 21;
        
        //打印
        System.out.println("p1对象");
        tool.printPerson(p1);
    
        //进行复制操作
        Person p2 = tool.copyPerson(p1);//用p2来接受返回的p
        //到此p1和p2都是两个独立的对象,只是属性相同
        System.out.println(p1.name==p2.name + "\n");//true
        
        p1.name = "小王";
        //注意这里对p1.name对赋值之后,王志珂 是存在新开辟的字符串空间之中的
        System.out.println("p2对象");
        tool.printPerson(p2);
        
        System.out.println("修改后的p1");
        tool.printPerson(p1);
        System.out.println(p1.name==p2.name);//false
    }
}

class Person{
    String name;
    int age;
}

class MyTools{
    //编写一个方法 copyPerson,可以复制一个 Person 对象,
    //返回复制的对象。克隆对象, 注意要求得到新对象和原来的 
    //对象是两个独立的对象,只是他们的属性相同
    public Person copyPerson(Person p1) {
        Person p2 = new Person();
        p2.name = p1.name;//把原来对象的名字赋给p2.name
        p2.age = p1.age;//把原来对象的年龄名字赋给p2.age
        return p2;
    }
    
    public void printPerson(Person p) {
        System.out.println("姓名:" + p.name);
        System.out.println("年龄:" + p.age);
        System.out.println();
    }
}