面向对象02-成员方法-Java

本文详细介绍了Java中的类成员方法,包括方法定义、使用、调用机制,以及基本数据类型和引用数据类型的传参方式。讲解了访问修饰符、返回值类型、形参列表和注意事项,还提供了实例和练习题帮助读者理解和应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本笔记是对韩顺平老师的Java课程做出的梳理。方便本人和观看者进行复习。
课程请见 https://www.bilibili.com/video/BV1fh411y7R8?p=209&spm_id_from=pageDriver&vd_source=ceab44fb5c1365a19cb488ab650bab03

		class 类名称 {
			成员变量;
			成员方法;
		}

一、方法简介

方法:表示类、对象的行为。方法在本质上是函数,是定义在类中的函数。

成员方法的定义

	访问修饰符 返回数据类型方法名(参数列表..){  //方法体
		语句;
		return返回值;
	}

1.参数列表:表示成员方法输入cal(int n)
2.数据类型(返回类型):表示成员方法输出, void表示没有返回值
3.方法主体:表示为了实现某一功能代码块
4.return语句不是必须的。
5.访问修饰符有四种 public、默认、protected、private

二、方法使用

  1. 方法写好后,如果不去调用(使用),不会生效。
  2. 先创建对象,然后调用方法即可。
		Person p1 = new Person(); //创建了一个对象
		p.speak(); //调用方法

示例 : Person类添加方法。

		class Person {
			String name;
			int age;
		}
  1. 添加speak成员方法,输出我是一个好人
  2. 添加cal01成员方法,可以计算从1+…+1000的结果
  3. 添加cal02成员方法,该方法可以接收一个数n,计算从1+…+n的结果
  4. 添加getSum成员方法,可以计算两个数的和
	public class Method01 {
		//编写一个main方法
		public static void main(String[] args) {
			Person p1 = new Person(); //创建了一个对象
			p1.speak(); //调用方法
			p1.cal01();
			p1.cal02(5);
			p1.cal02(7);
			int res = p1.getSum(3, 5);
			System.out.println(res);
		}
	}
	
	class Person {
		String name;
		int age;
		//1. 添加speak成员方法,输出我是一个好人
		//public表示方法是公开的,void表示方法没有返回值
		public void speak() {
			System.out.println("我是一个二次元");
		}
	
		//2.添加cal01成员方法,可以计算从1+..+1000的结果
		public void cal01() {
			int sum = 0;
			for(int i = 1; i <= 1000; i++) {
				sum += i;
			}
			System.out.println("计算结果 = "+sum);
		}
		//3.添加cal02成员方法,该方法可以接收一个数n,计算从1+..+n的结果
		public void cal02(int n) {
			int sum = 0;
			for(int i = 1; i <= n; i++) {
				sum += i;
			}
			System.out.println("计算结果 = "+sum);
		}
		//4.添加getSum成员方法,可以计算两个数的和
		public int getSum(int a, int b) {
			int sum = a + b;
			return sum;
		}
	
	}

运行结果:
在这里插入图片描述

三、方法调用机制

接上文,对下述代码进行分析:
代码块一

   //main方法里
		Person p1 = new Person(); //创建了一个对象
		int res = p1.getSum(3, 5);
		System.out.println(res);

代码块二

	public int getSum(int a, int b) {
		int res = a + b;
		return res;
	}

代码块一是在main方法里面的,存在于栈中(为方便理解起名为 main栈)

语句 int res = p1.getSum(3, 5);是从右往左执行
当执行到 p1.getSum的时候,会在栈中再开一个空间(独立的空间),为方便理解起名为 getSum栈。在getSum栈中进行函数的操作。且返回 res之后就会释放栈的空间。
在这里插入图片描述

总结【重要】

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

四、为什么用方法

提高代码的复用性
可以将实现的细节封装起来,然后供其他用户来调用即可。

五、注意事项与使用细节

	访问修饰符 返回数据类型方法名(参数列表..){  //方法体
		语句;
		return返回值;
	}

1 访问修饰符

作用:控制方法的适用范围
如果不写,就"默认访问",[总共有四种:public、protected、private、默认]

2 返回数据类型

(1)一个方法最多有一个返回值
[思考,如何返回多个结果?] :返回数组

	public class MethodDetail {
		//编写一个main方法
		public static void main(String[] args) {
			AA a = new AA();
			int[] res = a.getSumAndSub(4,1);
		}
	}
	
	class AA {
		public int[] getSumAndSub(int n1, int n2) {
			int[] res = new int[2]; //创建一个数组
			res[0] = n1 + n2;
			res[1] = n1 - n2;
			return res; 
		}
	}

(2)返回类型可以为任意类型,包含基本类型或引用类型(数组,对象)
在这里插入图片描述
(3)如果方法要求有返回数据类型,则方法体中最后的执行语句必须为return值;而且要求返回值类型必须和return的值类型一致或兼容
(4)如果方法是void,则方法体中可以没有return语句,或者只写 return ;
(5)方法名:遵循驼峰命名法,最好见名知义,表达出该功能的意思即可,比如得到两个数的和getSum,开发中按照规范

3 形参列表

(1)一个方法可以有0个参数,也可以有多个参数,中间用逗号愿开,比如getSum(int n1,int n2)
(2)参数类型可以为任意类型,包含基本类型或引用类型,比如printArr(int[][] map)
(3)调用带参数的方法时,一定对应着参数列表传入相同类型或兼容类型的参数
getSumAndSub 函数的参数是 int,传参的时候可以把比 int 低精度的数值传入(比如byte),但不可以传高精度的,比如double类。

    AA a = new AA();
	byte b1 = 1;
	byte b2 = 2;
	a.getSumAndSub(b1, b2);
	class AA {
		public int[] getSumAndSub(int n1, int n2) {
			int[] res = new int[2]; //创建一个数组
			res[0] = n1 + n2;
			res[1] = n1 - n2;
			return res; 
		}
	}

(4)方法定义时的参数称为形式参数,简称形参;
方法调用时的参数称为实际参数,简称实参;
实参和形参的类型要一致或兼容、个数、顺序必须一致
(5)方法体:里面写完成功能的具体的语句,可以为输入、输出、变量、运算、分支、循环、方法调用,但里面不能再定义方法!即:方法不能嵌套定义

如下这种形式就是错的

	public void f4() {
		public void f5() {
			
		}
	}

4 方法的调用

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

	public class MethodDetail {
		public static void main(String[] args) {
			A a2 = new A();
			a2.sayOk();
		}
	}
	class A {
		public void printA(int n) {
			System.out.println("printA方法被调用 n="+n);
		}
	
		public void sayOk() {
			printA(10);
		}
	}

在这里插入图片描述
(2)跨类中的方法A类调用B类方法:需要通过对象名调用。
比如:对象名.方法名(参数)

	public class MethodDetail {
		//编写一个main方法
		public static void main(String[] args) {
			A a2 = new A();
			a2.myfunc();
		}
	}
	
	class A {
		public void myfunc() {
		    System.out.println("myfunc方法开始执行");
			B b = new B(); //创建一个B对象
			b.hi();//调用
			System.out.println("myfunc方法继续执行:)");
		}
	}
	
	class B {
		public void hi() {
			System.out.println("B类跟你say hi");
		}
	}

在这里插入图片描述

(3)特别说明一下:跨类的方法调用和方法的访问修饰符相关,先暂时这么提一下,后面我们讲到访问修饰符时,还要再细说。

六、练习题

  1. 编写类AA新方法:判断一个数是奇数odd还是偶数,返回 boolean
  2. 根据行、列、字符打印对应行数和列数的字符,比如:行:4,列:4,字符
    #,则打印相应的效果
	public class practice01 {
		public static void main(String[] args) {
			AA testa = new AA();
			if(testa.isOdd(2)) System.out.println("是奇数\n");
			else System.out.println("是偶数\n");
	
			System.out.println("-----打印----\n");
	
			testa.myPrint(3,4,'#');
		}
	}
	
	class AA {
		public boolean isOdd(int x) { //odd是奇数
			if(x % 2 == 0) return false;
			else return true;
		}
	
		public void myPrint(int row, int col, char c) {
			for(int i = 0; i < row; i++) {
				for (int j = 0; j < col; j++) {
					System.out.println(c);
				}
				System.out.println('\n');
			}
		}
	}

这样输出是错误的
在这里插入图片描述
System.out.println() 自带换行
如果不想换行,换成System.out.print() 输出就是正常的
在这里插入图片描述

代码改进:三元运算符替代简单的 if-else

		return x%2 == 0?false:true;
		return x%2!=0;

七、方法传参机制

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

结论:基本数据类型,传递的是值(值拷贝),形参的任何改变不影响实参!

	public class MethodParameter {
		public static void main(String[] args) {
			Solution obj = new Solution();
			int a = 10;
			int b = 20;
			obj.swap(a,b);//调用swap方法
			System.out.println("\nswap函数结束后\na="+a+"\tb="+b);
		}
	}
	
	class Solution {
		public void swap(int a, int b) {
			System.out.println("\nab交换前\na="+a+"\tb="+b);
			int tmp = a;
			a = b;
			b = tmp;
			System.out.println("\nab交换后\na="+a+"\tb="+b);
		}
	} 

在这里插入图片描述
在这里插入图片描述
main函数和swap方法在栈里面是独立的空间。而且传递的是基本数据类型,不是引用。

2 引用数据类型的传参机制

结论:引用类型传递的是地址(传递也是值,但是值是地址),可以通过形参影响实参!

//引用数据的传参类型
	public class MethodParameter02 {
		public static void main(String[] args) {
			B b = new B();
			int[] arr = {1, 2, 3};
			b.test100(arr);
	
			System.out.println("main方法");
			for(int i = 0; i < arr.length; i++) {
				//数组长度
				System.out.print(arr[i] + "\t");
			}
			System.out.println();
	
	    }
	}
	
	class B {
		public void test100(int[] arr) {
			System.out.println("test100方法");
			arr[0] = 100;
			for(int i = 0; i < arr.length; i++) {
				System.out.print(arr[i] + "\t");
			}
			System.out.println();
		}
	} 

注意: 数组长度 arr.length
在这里插入图片描述
arr 数组是引用类型,也会指向堆空间(堆:存放由程序员new创建的对象和数组)
在这里插入图片描述

示例一

	//引用数据的传参类型
	public class MethodParameter02 {
		public static void main(String[] args) {
			B b = new B();
			Person p = new Person();
			p.name = "jack";
			p.age = 200;
			b.test200(p);
			System.out.println("main 的 p.name="+p.name+"\tp.age="+p.age);
	    }
	}
	
	class Person {
		String name;
		int age;
	}
	
	class B {
		public void test200(Person p) {
			p.age = 10000;
			p.name = "test200";
		}
	} 

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

示例二

上述代码修改如下,请问main函数输出的内容是?

	//引用数据的传参类型
	public class MethodParameter02 {
		public static void main(String[] args) {
			B b = new B();
			Person p = new Person();
			p.name = "jack";
			p.age = 10;
			b.test200(p);
			System.out.println("main 的 p.name="+p.name+"\tp.age="+p.age);
	
	    }
	}
	
	class Person {
		String name;
		int age;
	}
	
	class B {
		public void test200(Person p) {
			p = null;
		}
	} 

在这里插入图片描述

在这里插入图片描述

  • 上述代码再次修改,请问main函数输出的内容是?
    答:输出还是 jack 和 10
	//引用数据的传参类型
	public class MethodParameter02 {
		public static void main(String[] args) {
			B b = new B();
			Person p = new Person();
			p.name = "jack";
			p.age = 10;
			b.test200(p);
			System.out.println("main 的 p.name="+p.name+"\tp.age="+p.age);
	
	    }
	}
	
	class Person {
		String name;
		int age;
	}
	
	class B {
		public void test200(Person p) {
			p = new Person();
			p.name = "tom";
			p.age = 99;
		}
	} 

八、练习

  1. 编写MyTools类,编写一个方法可以打印二维数组的数据。
  2. 编写一个方法copyPerson,可以复制一个Person对象,返回复制的对象。克隆对象,
    注意要求得到新对象和原来的对象是两个独立的对象,只是他们的属性相同
	public class practice02 {
		public static void main(String[] args) {
			MyTool my = new MyTool();
			int[][] arr1 = {{1,2,3},{4,5,6},{7,8,9},{0,1,2}};
			my.printArr(arr1);
	
	        //最初的origin对象(Person类)
			Person origin = new Person();
			origin.name = "origin01";
			origin.age = 1;
			//复制
			Person copyone = my.copyPerson(origin);
	
			System.out.println("origin.name="+origin.name+"\torigin.age="+origin.age);
			System.out.println("copyone.name="+copyone.name+"\tcopyone.age="+copyone.age);
	
			//至此origin和copyone 是两个对立的对象,属性相同
	    }
	}
	
	class MyTool {
		public void printArr(int[][] arr) {
			for(int i = 0; i < arr.length; i++) {
				for(int j = 0; j < arr[i].length; j++) {
					System.out.print(arr[i][j]+"\t");
				}
				System.out.println();
			}
		}
	
		public Person copyPerson(Person p) {
			Person copy1 = new Person();
			copy1.name = p.name;
			copy1.age = p.age;
			return copy1;
		}
	}
	
	class Person {
		String name;
		int age;
	}

在这里插入图片描述

这里可以通过比较对象,查看对象是否为同一个。
由输出可知 copyone 和 origin是不一样的对象,只是属性相同而已。

	System.out.println(copyone == origin);

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值