方法
一、快速入门
public class Method01 {
public static void main(String[] args) {
//方法使用
//1.方法写好不调用不会生效
//2.使用:先创建一个对象然后调用
Person p1 = new Person(); //创建对象
p1.speak(); //调用方法speak
p1.cal01(); //调用方法cal01
p1.cal03(4); //调用方法cal03,同时赋值给n=4
int returnRes = p1.cal04(1,2);
//调用方法cal04,把方法返回的值赋给变量returnRes
System.out.println("cal04方法返回的值=" + returnRes);
}
}
class Person{
int age;
String name;
//方法
//1.public表示方法公开
//2.void表示方法没有返回值
//3.speak()方法名
//4.{}方法体,可以写我们要执行的代码
//方法1:输出一句话
public void speak(){
System.out.println("你好!今天天气真好!");
}
//方法2:计算1+2+...+1000
public void cal01(){
int res = 0;
for (int i = 0; i < 1001; i++) {
res += i;
}
System.out.println("计算结果=" + res);
}
//方法3:接收一个数字,计算1+2+...+n
//1.(int n)表示形参列表n,可以接收用户输入
public void cal03(int n){
int res = 0;
for (int i = 0; i <= n; i++) {
res += i;
}
System.out.println("计算结果=" + res);
}
//方法4:接收一个数字,计算两个数字的和
//1.public表示方法是公开的
//2.int 表示方法执行后返回一个int
//3.cal04方法名
//(int n, int m)两个形参
public int cal04(int n, int m){
int res = 0;
res = m + n;
return res;
}
}
二、方法的调用机制
- 首先执行main方法 ==> 在栈中开辟一个main栈空间
- Person p1 = new Person(); ==> 在堆中产生一个对象,p1指向这个对象
- int returnRes = p1.cal04(1,2); ==> 在栈中再开一个新的栈空间cal04
n指向1,m指向2 - return res; ==> 结果返回到p1.cal04(1,2),同时栈空间cal04被销毁
- main栈里面的所有程序都执行完毕后main栈也销毁,同时我们整个程序也销毁
三、方法的妙用
1. 提高代码复用性
2. 将实现细节封装起来,然后供其他用户使用
public class Method02 {
public static void main(String[] args) {
int [][] map = {{0, 0, 1},{1, 1, 1},{1, 1, 3}};
//遍历一个数组,输出各个元素值
//使用方法完成输出,创建Mytools对象,调用方法
Mytools mytools = new Mytools();
mytools.printArr(map);
//传统方法:直接遍历
// for (int i = 0; i < map.length; i++) {
// for (int j = 0; j < map.length; j++) {
// System.out.print(map[i][j] + " ");
// }
// System.out.println();
// }
//要求再次遍历时:代码冗余度太高
//思路:定义Mytools类,写一个成员方法,
//把功能写到一个类的方法中,然后调用方法
}
}
class Mytools{
//方法:接受二维数组
public void printArr(int[][] map){
//对传入的二维数组进行遍历
System.out.println("========");
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map.length; j++) {
System.out.print(map[i][j] + " ");
}
System.out.println();
}
}
}
四、方法的定义
public 返回数据类型 方法名(形参列表){ //方法体
语句
return 返回值
}
五、方法的使用细节(重点)
public 返回数据类型 方法名(形参列表){ //方法体
语句
return 返回值
}
1. 访问修饰符:控制方法使用范围
public protected 默认 private
2. 返回数据类型
2.1 一个方法最多有一个返回值【思考:如何返回多个类型?返回数组!】
2.2 返回类型可以为任意类型,包括基本类型和引用类型(数组、对象)
public class MethodDetail {
public static void main(String[] args) {
AA a = new AA(); //创建对象然后调用方法
int[] res = a.getSumAndSub(1,4); //返回数组
System.out.println("和=" + res[0]);
System.out.println("差=" + res[1]);
}
}
class AA {
//返回两个数的和and差
public int[] getSumAndSub(int n1, int n2){
int resArr[] = new int[2]; //创建一个数组
resArr[0] = n1 + n2;
resArr[1] = n1 - n2;
return resArr;
}
}
2.3 若有要求返回类型,必有return,要求返回类型与return值一致或兼容
public double f1(){
double d1 = 1.1 * 3;
// return d1;
int n = 1;
return n; //小传大肯定可以,反之不成
}
2.4 若方法是void,则不用写return语句,或者只写return;
3. 形参列表
3.1 形参数量:零参数或多参数,中间用逗号隔开,如getSum(int n, int m)
3.2 形参类型:基本类型or引用类型(数组、对象),如printArr(int[][] map)
3.3 形参与实参的类型要一致或兼容,个数,顺序必须一致,形参大实参小
4. 方法体
具体功能的语句,可以为输入、输出、变量、运算、分支、循环、方法调用,但里面不能调用方法
//细节:方法不能嵌套,方法是属于类的
public void f4(){
public void f5(){
}
}
5. 方法调用
5.1 同一个类中:直接调用,不需要创建对象并实例化
5.2 跨类:通过对象名调用
package chapter07;
public class MethodDetail02 {
public static void main(String[] args) {
A a = new A();
a.sayOk();
a.m1();
}
}
class A {
//同一个类中:直接调用
public void print(int n){
System.out.println("print方法被调用 n = " + n);
}
public void sayOk(){ //sayOk中调用print
print(10);
System.out.println("继续执行sayOk()");
}
//跨类中的方法A类调用B类方法:通过对象名调用
//A类中的m1()方法调用B类中的hi()方法
public void m1(){
//创建B类的对象,然后实例化
System.out.println("m1方法被调用:)");
B b = new B();
//对象调用
b.hi();
System.out.println("m1方法继续执行:)");
}
}
class B {
public void hi(){
System.out.println("B类中的hi方法被执行");
}
}
六、成员传参机制
1. 基本数据类型传参机制
package chapter07;
public class MethodParaMeter01 {
public static void main(String[] args) {
int a = 10;
int b = 20;
//创建AA对象
A1 aa = new A1();
aa.swap(a,b);
System.out.println("a=" + a + "b=" + b); //a=10,b=20
}
}
class A1 {
public void swap(int a, int b){
System.out.println("\na和b交换前的值\na="+ a + "\tb=" + b);//a=10,b=20
//完成a和b的交换
int t = a;
a = b;
b = t;
System.out.println("\na和b交换后的值\na="+ a + "\tb=" + b);//a=20,b=10
}
}
2. 引用数据类型传参机制
引用类型传递的是地址(传递也是值,但是值是地址),可以通过形参影响实参
package chapter07;
public class MethodParaMeter02 {
public static void main(String[] args) {
int[] arr = {2, 2, 2, 2};
BB bb = new BB();
bb.getArr(arr);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
Personn p = new Personn();
p.name = "Jack";
p.age = 10;
bb.test200(p);
//测试题目:如果test200执行的是 p = null, 下面结果输出10,为啥不是null呢
//因为p = null是将test200栈里面的p置空,但未曾改变对象,main栈里面的p仍然指向之前的对象
//测试题目:如果test200执行的是 p = new Personn(); 下面结果输出10
//当调用test200时,p指向main栈指向的p,但是在test200栈又创建了p对象,所以test200中的p指向新的对象,但是输出的依然是main栈中的p指向的对象
System.out.println("main的p.age为:" + p.age);
}
}
class Personn {
String name;
int age;
}
class BB {
public void test200(Personn p){
// p.age = 1000;//修改对象属性
// p = null;
p = new Personn();
p.name = "tom";
p.age = 99;
}
public void getArr(int[] arr){
arr[0] = 1;
}
}
3. 克隆对象
package chapter07;
/***
* 要求:编写方法copyPerson,复制一个Person对象,返回复制的新对象,注意这是两个新对象
* 1.新建一个person对象p
* 2.新建一个copyPerson方法,传入参数为p,返回参数为Person类型,返回ppp并赋值给ppp
*/
public class MethodExercise02 {
public static void main(String[] args) {
person p = new person();
p.name = "小明";
p.age = 12;
Mytool mytool = new Mytool();
person ppp = mytool.copyPerson(p);
//到此p和ppp都是person对象,并且属性相同
System.out.println(ppp.age);
System.out.println(ppp.name);
//可以同对象比较看看是否为同一个对象,如果p和ppp是同一个对象则返回true
System.out.println(p == ppp);
}
}
class person{
String name;
int age;
}
class Mytool{
person copyPerson(person p){
person ppp = new person();
ppp.age = p.age;
ppp.name = p.name;
return ppp;
}
}