JAVA 方法
目录
方法
概念:在某些情况下,我们要需要定义成员方法(简称方法)。比如人类:除了有一些属性外( 年龄,姓名..),我们人类还有一 些行为比如:可以说话、跑步..,通过学习,还可以做算术题。这时就要用成员方法才能完成。
一、方法的调用机制
- 当程序执行到方法时,就回开辟一个独立的空间(栈空间)
- 当方法执行完毕,或者执行到return语句时,就回返回
- 返回到调用的地方
- 返回后,继续执行方法后面的代码
- 当main方法(栈),执行完毕,整个程序就退出
二、成员方法
为什么需要成员方法
- 提高了代码的复用性,减少了代码的冗余
- 可以将实现的细节封装起来,供其他用户使用
- 利于开发,提高开发效率
例如:
题目:请遍历一个数组 , 输出数组的各个元素
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 返回值;
}
- 形参列表:表示成员方法的输入
- 返回数据类型:表示成员方法输出, void 表示没有
- 方法主体:表示为了实现某一功能代码块
- return 语句不是必须的,当有个具体的返回数据类型时,就必须要有个return 语句
2.2注意事项和细节
访问修饰符
作用:是控制方法使用的范围
- 如果不写默认访问
- public 表示方法公开
- protected
- 默认
- private
返回数据类型
-
一个方法最多有一个返回值
- 思考:如果要返回多个返回值
- 可以返回数组
- 思考:如果要返回多个返回值
-
返回类型可以为任意类型,包含基本类型或引用类型(数组,对象)
-
如果方法要求有返回数据类型,则方法体中最后的执行语句必须为 return 值; 而且要求返回值类型必须和 return 的 值类型一致或兼容
- 没有办法把高精度的转换成低精度的
-
如果方法是 void,则方法体中可以没有 return 语句,或者 只写 return
方法名
在实际工作中,我们的方法都是为了完成某个功能,所以方法名一定要有某个含义
- 遵循驼峰命名法,最好见名知义,表达出该功能的意思即可, 比如 得到两个数的和 getSum, 开发中按照规
形参列表
- 一个方法可以有0个参数,也可以有多个参数,中间用逗号隔开
- 参数类型可以是任意类型
- 调用带参数的方法时,一定对应着参数列表传入相同类型或兼容的类型
- 方法定义的时候称为形参,简称形参;方法调用时用的参数为实际参数,简称实参,实参和形参的类型要一致或兼容、个数、顺序必须一致!
方法体
方法体不能嵌套定义,但是可以使用方法
方法调用
-
同一个类中的方法调用:直接调用即可
-
跨类中的方法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()方法被执行"); } }
-
-
特别说明:
- 跨类的方法调用和方法的访问修饰符相关
三、方法练习题
题目:编写类 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;
}
运行效果:
结论:
- 引用类型传递是地址(地址也是指,但值是地址),可以通过形参的改变来改变实参
- 对象也是引用类型的,故在方法中修改对象的值,也会修改对象的值
- 如果对象名相同,但地址不通,则优先调用主在原本的对象的值
内存空间示意图
练习
题目:
编写一个方法 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();
}
}