【Java学习笔记】19 成员方法

目录

一、基本介绍

二、快速入门

三、方法调用的机制

总结

四、成员方法的好处

五、成员方法的定义

返回数据类型

方法名

形参列表

方法体

方法调用

六、成员方法的练习

1.编写方法判断奇偶

2.打印对应列行数的字符

七、成员传参的机制

1.基本数据类型

2.引用类型

八、练习 克隆对象


一、基本介绍

        在某些情况下,我们需要定义成员方法。比如人类:除了有属性以外,人类还有一些行为:说话,跑步;这时候就需要用成员方法才能完成,对Person类完善

二、快速入门

                

1)

public class Object01{
	public static void main(String[] args){
		//方法使用 先创建对象 然后调用方法即可 
		Person p1 = new Person();
		p1.speak();//调用方法 程序执行到这里会去person类里找speak方法
	}
}
class Person{
	String name;
	int age;
	//public 表示是公开的  void表示方法没有返回值 
	//speak() 表示方法名 ()表示形参列表
	//{}方法体,可以写我们要执行的代码
	//System.out...表示方法内容,输出一句话
	//方法写好后,不去调用不会输出语句
	public void speak(){
		System.out.println("我是一个好人");
	}
}

2)

public class Method01{
	public static void main(String[] args){
		p1.cal01();
	}
}
class Person{
	public void cal01(){//计算从1+...+1000
		int sum = 0;
		for(int i = 1; i <= 1000 ;i++){
			sum += i;
		}
		System.out.println(sum);
	}
}

                

3)

p1.cal02(5);//调用方法的时候 给形式参数一个数值 即把5传给了n
	
//()表示目前有一个形参n 形式参数,可以接受用户输入
public void cal02(int n){
		int sum = 0;
		for(int i = 1; i <= n ;i++){
			sum += i;
		}
		System.out.println(sum);
	}

4)

public class Method01{
	public static void main(String[] args){
        Person p1 = new Person();
		int returnRes = p1.getSum(10,20);//方法getSum返回的值赋给returnRes
		System.out.println(returnRes);
		System.out.println(p1.getSum(10,20));//同上,这个方法可以直接打印出来
	}
}
class Person{
	//public 表示方法是公开的
	//int 表示方法执行后 返回一个int可以自行接收
	//getSum表示方法名
	//(int num1,int num2)表示可以接受用户传入的两个参数
	//return res表示把res的值返回
	public int getSum(int num1,int num2){
		int res = num1 + num2;
		return res;
	}
}

三、方法调用的机制

        Person p1 = new Person();

        int returnRes = p1.getSum(10,20);//方法getSum返回的值赋给returnRes
        System.out.println(returnRes);

    public int getSum(int num1,int num2){
        int res = num1 + num2;
        return res;
    }

第一行创建对象,会在堆创建一个的数据空间,这行代码在main栈(只是为了方便区分,底层不会对栈进行命名)执行,意思就是p1指向堆里的一个数据空间,叫数据对象;

第二行先执行等号右边,会在栈内创建一个数据空间,getSum栈(底层没有这个名字只是为了方便区分),会跳到对应的方法,public int getSum,随后执行方法内容,执行完return res之后从getSum栈有一个int数据类型返回给main栈内的p1.getSum(),注意,当返回完之后getSum栈会销毁。然后执行等号的左边,赋值给returnRes。

总结

        1.当程序执行到方法时,会开辟一个独立的空间(栈空间)

        2.当方法执行完毕,或者执行到return语句时,就会返回,返回完之后数据空间会销毁

        3,返回到调用方法的地方

        4.返回后,继续执行后面的方法

        5.当main方法执行完毕,整个程序会退出

四、成员方法的好处

        

//传统方法
public class Method02{
	public static void main(String[] args){
		int[][] map = {{0,0,1},{1,1,1},{1,1,3}};
		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.print(" ");
		}
	}
}

                

传统的解决方式就是直接遍历,而且如果要多次调用会很麻烦,只能复制一份放在对应的地方,代码冗余。考虑定义一个类MyTools 然后写一个方法

public class Method02{
	public static void main(String[] args){
		int[][] map = {{0,0,1},{1,1,1},{1,1,3}};
		Mytools tools = new Mytools();
		tools.for01(map);
	}
}
class Mytools{
	public void for01(int[][] map){//map的名字和main栈的不冲突,可以使用
		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.print(" ");
		}
	}
}

好处,可以实现细节的封装,其他用户来调用即可

五、成员方法的定义

        public 返回数据类型 方法名(参数列表..){//方法体

                语句;

                return 返回值;

        }

1.参数列表:表示成员方法输入 cal(int n)

2.数据类型(返回类型):表示成员方法输出,void表示没有返回值

3.方法主题:表示为了实现某一功能代码块

4.return语句不是必须的

5.访问修饰符(作用是控制 方法使用的范围)

        如果不写会有默认值 (有四种 public protected  默认 private)

返回数据类型

1.一个方法最多只有一个返回值 需要返回多个数据可以使用数组

2.返回数据可以是任意类型

3.如果方法要求有返回值,那么在方法内容里一定要包含return返回语句,返回可以是一个变量或者常量,需要满足自动转换

4.如果方法体是void 可以不写return 或者只写return 后面不能带有返回的值

方法名

应该使用驼峰命名法 setSum showArr等 aaBbbCcc类型,方法名应当有一定含义

形参列表

1.一个方法可以有0个参数,也可以有多个参数,中间用逗号隔开,例如speak(int n1,int n2)

2.参数类型可以为任意类型,包含基本类型和引用类型比如(int arr[])

3.调用带参数的方法时,一定对应着参数列表传入相同类型或者兼容类型

4.方法调用时,实际传入的参数叫实参,实参和形参传的兼容类型、个数、顺序,必须一致

方法体

里面写完成功能的具体语句,可以为输入、输出、变量、循环等等,但不能再定义方法,即方法不能嵌套方法

方法调用

1.同一个类的方法调用:直接调用即可比如print(参数)

        

class A{
    public void print(int n1){
        System.out.print("ok" + n1);
    }
    public void sayOk(){
        print(10)
    }
}

2.跨类中的方法A类调用B类:需要通过对象名调用。比如 对象名.方法名(参数);


class A{
    public void m1(){
        B hello = new B();
        hello.h1();
    }
}
class B{
    public void h1(){
        System.out.print("b类的h1方法");
    }
}

3.特别说明:跨类的方法调用和方法的访问修饰符相关,到访问修饰符时会详讲

        跟pubilc、包有很大的关系

六、成员方法的练习

1.编写方法判断奇偶

import java.util.Scanner;
public class MethodExercise01{
	public static void main(String[] args){
		int enter = 0;
		Scanner myScanner = new Scanner(System.in);
		System.out.println("请输入一个数,判断是否是偶数");
		enter = myScanner.nextInt();
		AA num = new AA();
		num.determineParity(enter);

	}
}
class AA{
	public void determineParity(int n1){
		if(n1 % 2 == 0){
			System.out.println("这个数是偶数");
		}
		else{
			System.out.println("这个数是奇数");
		}
	}
}

2.打印对应列行数的字符

import java.util.Scanner;
public class MethodExecrise02{
	public static void main(String[] args){
		int hang = 0;
		int lie = 0;
		char zifu;
		Scanner myScanner = new Scanner(System.in);
		System.out.println("请输入行数");
		hang = myScanner.nextInt();
		System.out.println("请输入列数");
		lie = myScanner.nextInt();
		System.out.println("请输入字符");
		zifu = myScanner.next().charAt(0);
		PrintOut outPut = new PrintOut();
		outPut.arrPrint(hang,lie,zifu);
	}
}
class PrintOut{
	public void arrPrint(int hang,int lie,char zifu){
		for(int i = 0;i < hang;i++){
			for(int j = 0;j < lie;j++){
				System.out.print(zifu + "\t");
			}
			System.out.println();
		}
	}
}

七、成员传参的机制

1.基本数据类型

                

public class MethodParameter{
	public static void main(String[] args){
		int a = 10;
		int b = 20;
		AA aa = new AA();
		aa.swap(a,b);
		System.out.println(" a=" + a + "\tb=" + b);

	}
}
class AA{
	public void swap (int a,int b){
		System.out.println("交换前的值a=" + a + "\tb=" + b);
		int temp = a;
		a = b;
		b = temp;
		System.out.println("交换后的值a=" + a + "\tb=" + b);

	}
}

        

这里是拷贝赋值,所以改变方法内的元素不会改变main方法内的数值的值

        

2.引用类型

        

public class MethodParameter02{
	public static void main(String[] args){
		B myTools = new B();
		int[] arr = {10,20,50,15,100};
		myTools.printArr(arr);
		myTools.swap(arr);//注意传递数组应该是数组名而不加[]
		myTools.printArr(arr);
	}
}
// class Persong{
// 	String name;
// 	int age;
// }
class B{
	public void swap (int arr[]){
		for(int i = 0;i < arr.length; i++){
			int min = 0;
			for (int j = 0; j < i; j++){
				if(arr[j] > arr[j + 1]){
					min = arr[j];
					arr [j] = arr[j + 1];
					arr [j + 1] = min;
				}
			}
		}
		printArr(arr);
	}
	public void printArr(int arr[]){
		System.out.println("");
		for(int i = 0; i < arr.length; i++){//打印数组
			System.out.print(arr[i] + "\t");
		}
	}
}

很好理解,因为是引用赋值,所以数值的改变会影响指向的堆内的值,所以访问的同一地址的值都会发生改变

                

意思就是在引用赋值中,形参也会影响实参

public class MethodParameter03{
	public static void main(String[] args){
		Person p = new Person();//声明对象,实例化一个对象
		B b = new B();
		p.name = "jack";//对象属性赋值
		p.age = 20;
		b.test200(p);
		System.out.println("main方法内的p.age = " + p.age);
	}
}
class Person {
	String name;
	int age = 0;
}
class B{
	public void test200(Person p){//这里面的Person p是声明了一个对象
		//在实际参数向形式参数的传递中可以不开辟空间 前提是要开过这个空间
		p.age = 20000;
	}
}

                

很好理解,main方法内的值也发生了改变,因为是同一地址指向    

                

注意,对于方法间的数据传递机制还有

                

public class MethodParameter03{
	public static void main(String[] args){
		Person p = new Person();//声明对象,实例化一个对象
		B b = new B();
		p.name = "jack";//对象属性赋值
		p.age = 20;
		b.test200(p);
		System.out.println("main方法内的p.age = " + p.age);
	}
}
class Person {
	String name;
	int age = 0;
}
class B{
	public void test200(Person p){//这里面的Person p是声明了一个对象
		//在实际参数向形式参数的传递中可以不开辟空间 前提是要开过这个空间
		p = null;
	}
}

                

现在p置空,main方法内的p.age并不会抛出一个异常,因为在test200方法内改变的是形式参数,我的理解 实参在向形参传递的过程中test200内的 p = p;前一个p是test200的形式参数,后一个是main传来的实际参数,

随后 p = null 这时候改变的是test200的形式参数,所以p并没有办法影响main的属性

                

如果是

public class MethodParameter03{
	public static void main(String[] args){
		Person p = new Person();//声明对象,实例化一个对象
		B b = new B();
		p.name = "jack";//对象属性赋值
		p.age = 20;
		b.test200(p);
		System.out.println("main方法内的p.age = " + p.age);
	}
}
class Person {
	String name;
	int age = 0;
}
class B{
	public void test200(Person p){//这里面的Person p是声明了一个对象
		//在实际参数向形式参数的传递中可以不开辟空间 前提是要开过这个空间
		// p.age = 20000;
		// p = null;
		p = new Person();
		p.name = "tom";
		p.age = 999;
	}
}

注意,这时候在test200内创建了一个新的空间,意思就是形式参数的p不接收实参的地址值了,它新建了个空间指向堆里的地址,随后改变值什么的都不会影响main函数里面的值

                

八、练习 克隆对象

public class MethodExercise03{
	public static void main(String[] args){
		Person p = new Person();
		MyTools tools = new MyTools();
		p.name = "jack";
		p.age = 100;
		Person p2 = tools.copyPerson(p); 
		//声明对象Person p2,不需要创建新空间,这里的p2和Mytools的p2不一样
		p.name = "tom";//验证是否是独立对象
		System.out.println(p.name + p.age);
		System.out.println(p2.name + p2.age);
	}
}
class Person {
	String name;
	int age = 0;
}

class MyTools{//1.返回类型应该是Person 2.方法的形参应该是Person p 
	//3.方法体,创建一个新对象,并复制属性返回即可
	public Person copyPerson(Person p){
		Person p2 = new Person();
		p2.name = p.name;//属性的复制
		p2.age = p.age;//属性的复制
		return p2;//返回p2
	}
}

                

 //也可以使用==判断地址是否相同
        System.out.println(p == p);//true 是同一个地址所以一样
        System.out.println(p == p2);//false 不是同一个地址所以不一样

                 

                

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yinhai1114

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值