JAVA 方法

方法

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

一、方法的调用机制

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

posted @ 2022-01-15 20:51  DL50  阅读(42)  评论(0编辑  收藏  举报