【Java复健指南02】方法的注意事项
【方法】
方法基本内容
√访问修饰符
(作用是控制方法使用的范围)
可选,[有四种:public\protected\默认\private],具体在后面说
√返回类型
1.一个方法最多有一个返回值[思考,如何返回多个结果?]
2.返回类型可以为任意类型,包含基本类型或引用类型(数组,对象)
3.如果方法要求有返回数据类型,则方法体中最后的执行语句必须为return值;
而且要求返回值类型必须和return的值类型一致或兼容
4.如果方法是void,则方法体中可以没有return语句,或者只写return ;
√方法名
遵循驼峰命名法
√形参列表
1.一个方法可以没有参数,也可以有多个参数,中间用逗号开,比如getSum(int n1,int n2)
2.参数类型可以为任意类型,包含基本类型或引用类型,比如 printArr(int]map)
3.调用带参数的方法时,一定对应着参数列表传入相同类型或兼容类型的参数!【getSum】
4.方法定义时的参数称为形式参数,简称形参;
方法调用时的参数称为实际参数,简称实参。实参和形参的类型要一致或兼容、个数、顺序必须一致!
√方法体
里面写完成功能的具体的语句,可以为输入、输出、变量、运算、分支、循环、方法调用,
里面不能再定义方法!
即:方法不能嵌套定义。
例子1
public class MethodDetail{
public static void main(String[] agrs){
AA a = new AA();
int[] res = a.getsumAndSub(1,3);
System.out.println("和="+res[0]);
System.out.println("差="+res[1]);
//细节:调用带参数的方法时,一定对应着参数列表传入相同类型或兼容类型的参数
byte b1 = 1;
byte b2 = 2;
a.getSumAndSub(b1,b2);//byte -> int低精度给高精度类型是可以兼容的
}
}
class AA{
//1.一个方法最多有一个返回值[思考,如何返回多个结果?返回数组]
//返回类型为int[]
public int[] getsumAndSub(int n1, int n2) {
int[] resArr = new int[2];//创建一个数组
resArr[0] = n1 + n2;
resArr[1] = n1 - n2;
return resArr;
}
}
//如果方法是void,则方法体中可以没有return语句,或者只写return ;
public void f2(){
System.out.print1n("hello1");
System.out.print1n("hello1");
System.out.print1n("hello1");
int n = 10;
//return ;
}
例子2
public class MethodDetail02{
public static void main(String[] agrs){
/*
√方法细节调用说明
1.同一个类中的方法调用:直接调用即可。比如print(参数);
案例演示:A类sayOk调用print()
2.跨类中的方法A类调用B类方法:需要通过对象名调用。
比如对象名.方法名(参数);
案例演示:B类sayHello调用print()
3.特别说明一下:跨类的方法调用和方法的访问修饰符相关,先暂时这么提一下,
后面我们讲到访问修饰符时,还要再细说。
*/
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);
}
//跨类中的方法A类调用B类方法:需要通过对象名调用
public void m1() {
//创建B对象,然后在调用方法即可
System.out.println("m1()方法被调用");
B b = new B();
b.hi();
}
}
class B {
public void hi() {
System.out.println("B类中的hi()被执行");
}
}
练习
习题一
1、编写方法:判断一个数是奇数odd还是偶数,返回boolean
2、根据行、列、字符打印对应行数和列数的字符
public class MethodExercise01{
public static void main(String[] agrs){
AA a = new AA();
if(a.isOdd(2)){
System.out.println("t");
}else{
System.out.println("f");
}
a.print(10,10,"草");
}
}
//1.编写类AA新方法:判断一个数是奇数odd还是偶数,返回boolean
class AA{
//思路
//1.方法的返回类型boolean
//2.方法的名字isodd
//3.方法的形参1(int num)
//4.方法体,判断
public boolean isOdd(int num){
//朴素思路
// if(num % 2 == 0){
// return false;
// }else{
// return true;
// }
//还可以这么想
// return num % 2 ! = 0 ? true; false;
return num % 2 ! = 0;//最后可以简化成这个
}
//根据行、列、字符打印对应行数和列数的字符,
//比如:行:4,列:4,字符#,则打印相应的效果
/*
####
####
####
####
*/
//思路
//1.方法的返回类型void
//2.方法的名字print
//3.方法的形参(int row,int col, char c)
//4. 方法体,循环
public void print(int row, int col, String c){
for(int i = 0; i<row; i++){
for(int j = 0; j<col; j++){
System.out.print(c);
}
System.out.println();
}
}
}
习题二 方法克隆对象
编写一个方法copyPerson,可以复制一个Person对象,返回复制的对象。
克隆对象,注意要求得到新对象和原来的对象是两个独立的对象,只是他们的属性相同
public class MethodExercise02{
public static void main(String[] agrs){
Person p = new Person();
p.name = "m";
p.age = 100;
MyTools tool = new MyTools();
Person p2 = tool.copyPerson(p);
//到此 p和p2是Person对象,但是是两个独立的对象,属性相同
System.out.println("p的属性age=" + p.age+"名字=" + p.name);
System.out.println("p2的属性age=" + p2.age +"名字="+ p2.name);//提示:可以同对象比较看看是否为同一个对象
System.out.println(p == p2); //false
}
}
class Person{
String name;
int age;
}
class MyTools{
//思路
//1.方法的返回类型Person
//2.方法的名字copyPerson
//3.方法的形参(Person p)
//4.方法体,创建一个新对象并复制属性,返回
public Person copyPerson(Person p){
//这里的形参传入一个对象名,还没有真的开辟新空间
//创建一个新对象p2,开辟新的内存空间
Person p2 = new Person();
p2.name = p.name;
p2.age = p.age;
return p2;
}
}
习题三
public class MethodParameter01{
public static void main(String[] agrs){
int a = 10;
int b = 20;
AA obj = new AA();
obj.swap(a,b);
/*
main方法中的a、b与AA方法中的a、b存在于栈中不同的位置,因此使用时的值会不同
*/
System.out.println("main方法 a="+a+" "+"b="+b);//a 10 b 20
}
}
class AA{
public void swap(int a, int b){
System.out.println("\na和b交换前的值\na=" + a + "\tb=" + b);
//完成了a和b的交换
int tmp = a;
a = b;
b = tmp;
System.out.println("\na和b交换后的值\na=" + a + "\tb=" + b);
}
}
注意点:
不同方法中的变量位于不同的栈空间中,因此使用时是相互独立的
习题四 方法传入对象
B类中编写一个方法test100,可以接收一个数组,在方法中修改该数组,看看原来的数组是否变化?
答:会变化,该操作只是将数组地址传给方法,指向同一个数据内存空间
B类中编写一个方法test200,可以接收一个Person(age,sal)对象,在方法中修改该对象属性,看看原来的对象是否变化?
答:会变化,该操作只是将实例化后的对象的地址传给方法,也是指向同一个数据内存空间
public class MethodParameter02{
public static void main(String[] agrs){
//测试
B b = new B();
int[] arr = {1,2,3};
// b.test100(arr);
// System.out.println("main的arr数组");
// //遍历数组
// for(int i = 0; i < arr.length; i++) {
// System.out.print(arr[i] +"\t");
// }
// System.out.println();
Person p = new Person();
p.name = "jack";
p.age = 10;
b.test200(p);//把p的地址传给test200
//若test200执行的是p = null, 下面的输出是什么? 10
//原因:p = null只是把方法里的p置空,即指向一个空地址,
//不影响main中为p开辟的地址中的值(下面代码的p是main的)
//若test200执行的是p = new Person();, 下面的输出是什么? 10
//原因:栈中,main实例化了一个p,其在堆中产生一个对象
//此时main实例化的b调用了test200,因为其传入的参数是p,故此时该p与main中p指向堆中的同一处(age 10)
//随后在test200中又实例化了一个p,那么test200中的p会指向一个新的堆空间(age 99)
//因为打印语句的p在main中调用,所以打的是age等于10的那个堆的数据
//然后堆空间(age 99)会被当成垃圾回收
System.out. println("main的p.age=" + p.age);//100000
}
}
class Person{
String name;
int age;
}
class B{
public void test200(Person p){
// p.age = 100000;
//思考
// p = null;
//思考
p = new Person();
p.name = "tom";
p.age = 99;
}
//B类中编写一个方法test100,
//可以接收一个数组,在方法中修改该数组,看看原来的数组是否变化
public void test100(int[] arr){
arr[0] = 200;//修改元素
System.out.println("test100的arr数组");
for(int i = 0; i<arr.length; i++){
System.out.print(arr[i] + "\t");
}
System.out.println();
}
}