Java方法


Java方法

为什么要使用方法

生活中的方法(工具)

螺丝刀,锤子,扳手

1、提高复用度,可重复使用

2、提高效率

开发中使用方法来实现同样的效果,为了解决复用和效率的问题

概念

实现特定功能的一段代码,可以被反复使用

方法的构成

固定格式:
    public static
返回值类型:
    表示方法执行完成后返回的数据类型
    如果没有返回值类型就用 void ,如果有就使用对应的返回值类型
方法名:
    小驼峰命名,见名知意,动宾结构
形参列表:
    用来接收用户传入的数据,可以是基本数据类型或者引用数据类型,需要声明局部变量。
    如果不需要形参就写 (),如果有多个就写多个
方法体:
    {}

注意:

  1. 固定的格式(public static)不要问,因为不影响我们写代码,后期会讲!!!
  2. 方法要写上文档注释,为了更方便地阅读代码

方法声明格式

public static returnType methodName(dataType FormerParameter) {
    method body;
}

public static 返回值类型 方法名(数据类型 形参名) {
    方法体;
}

声明位置

定义在类中,与其他方法(main方法)并列

无返回值方法调用

mothodName(actualParameter);
方法名(实参);

注意:

方法和变量最大的区别就是方法后面有小括号,即便没有参数也有小括号

小驼峰

无参无返回值调用

class TestMethod1 {
    public static void main(String[] args) {
        printHelloWorld();
    }

    /**
    * 打印Hello World
    */
    public static void printHelloWorld() {
        System.out.println("Hello World");
    }
}

注意

  1. main方法是程序的入口,所有的代码和方法都需要在main方法中被完成和调用
  2. 方法名的后面一定要跟
  3. 方法和其他方法的关系是并列关系

有参无返回值调用

import java.util.Scanner;

class TestMethod3 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.println("请输入一个数:");
        int num = scanner.nextInt();

        printIntNum(num);
    }

    /**
    * 展示用户传入的int类型数据
    *
    * @param num 这里需要传入一个int类型的数据
    */
    public static void printIntNum(int num) {
        System.out.println("您输入的数为:" + num);
    }
}

注意:

  1. 如果方法声明时带有形式参数,那么方法调用时就必须携带实际参数1
  2. 如果方法声明时没有形式参数,方法调用时就不能有实参
  3. 声明时有几个形式参数,调用时就传入几个实际参数,形参实参个数不一样编译会报错
  4. 实参与形参的数据类型不一样,编译器会报错
  5. 实参与形参的顺序不一样,编译器会报错

形参与实参

形参:用来接收调用该方法时传递的参数。只有在被调用的时候才分配内存空间,一旦调用结束,就释放内存空间。因此仅仅在方法内有效。
实参:方法调用时用于传入的数据,用来给形参赋值,数据类型要求一致

形参举例

 public void swap(int a, int b) {
        int temp = a;
        a = b;
        b = temp;
        System.out.println("a:" + a + " b:" + b);
    } 
这里边的a,b就是形参,temp是一个局部变量,方法结束,在栈空间中就会被销毁

实参举例

调用上面的方法
swap(1,2);
其中12就是实际的参数值,就叫实参

返回值

方法中的返回值有两种情况,即有返回值和无返回值,如果定义方法时有返回值类型,就需要返回相对应的数据类型

基本数据类型
    值传递,不改变自身
引用数据类型
    引用传递,改变自身
void
    无返回值
1、一个方法只能有一个返回值
2、分支结构的每一个分支都需要正确的返回值
3、返回值可以接收也可以不接收

return 关键字

作用

结束当前方法,返回至调用方法处,如果定义了返回值类型就返回对应类型的数据

【注意】数据类型一致化

格式

return 需要返回的数据;

注意

1、单一职能原则,一个方法只做一件事
2、注意形参和实参数据类型一致化
3、返回值类型和参数没有关系
4、方法名要符合小驼峰命名规则
5、return的下一行代码不会执行

有返回值方法调用

无参有返回值的方法:give me five

class TestMethod1 {
    public static void main(String[] args) {
        System.out.println(giveMeFive());
    }

    /**
    * 返回一个整数 5
    *
    * @return 5 int类型
    */
    public static int giveMeFive() {
        return 5;
    }
}

有参有返回值的方法:两个数求和

public class MethodDemo6 {
    public static void main(String[] args) {
        /*
         * 调用自定义getSumOfTwoNumber方法,需要两个int类型的参数,并得到一个int类型的返回值
         * 
         * 参数列表一定要和方法声明上的参数类型完全一致
         */ 
        int total = getSumOfTwoNumber(1, 2);

        System.out.println(total);
    }

    /**
     * 两个整数进行求和
     * 
     * @param num1 求和的第一个数
     * @param num2 求和的第二个数
     * @return 返回两个参数的和,int类型
     */
    public static int getSumOfTwoNumber(int num1, int num2){
        return num1 + num2;
    }
}

注意:调用带有多参数的方法,要求传入的参数数据类型,个数和顺序还有数据类型必须和方法声明一致

规范化return

在一个方法中,return出现的次数要尽可能得少,为了提高阅读性和逻辑性

class TestMethod4 {
    public static void main(String[] args) {
        System.out.println(getCompare(3,2));
    }

    /**
    * 比较大小,返回较大的那个数
    *
    * @param num1 int类型
    * @param num2 int类型
    * @return int类型的结果
    */
    public static int getCompare(int num1, int num2) {
        return num1 > num2 ? num1 : num2;
    }
}

总结

1、break 是退出当前循环结构,return 是退出当前方法

2、如果返回值类型是 void ,可以返回 null 或者不返回或者 return;

3、一个方法可以有多个 return,但只能有一个返回值

4、返回值可以接收也可以不接收,由调用者决定如何调用

5、分支结构里的每一个分支都需要有正确的返回值

6、对返回值的处理方式因情况而定,可以打印、参与运算或者当做其他方法的实参

7、调用带有多参数的方法,要求传入的参数数据类型,个数和顺序和类型必须和方法声明一致

注意:方法具有单一职能原则,一个函数只做一件事

方法重载【Overload】

概念

一个类或者接口中定义多个相同名称的方法

要求

1、必须在同一个类中
2、方法名必须一致
3、参数必须不一致(个数,顺序,类型)    
4、与访问修饰符、返回值类型无关
public class MethodDemo9 {
    public static void main(String[] args) {
        // 调用同名方法,传入不同的参数列表,即可实现方法的重载
        play();
        play("英雄联盟");
        play("红色警戒", 2);
        play(1, "DNF");
    }

    public static void play() {
        System.out.println("玩王者荣耀");
    }

    public static void play(String gameName) {
        System.out.println("玩" + gameName);
    }

    public static void play(String gameName, int time) {
        System.out.println("玩" + gameName + time + "小时");
    }

    public static void play(int time, String gameName) {
        System.out.println("玩" + gameName + time + "小时");
    }

    /* 
     * Duplicate method play(String, int) in type MethodDemo9
     * 
     * 跟返回值类型无关,只关注方法名和参数类型
     */
//    public static String play(String gameName, int time) {
//        return "玩" + gameName + time + "小时";
//    }
}

优点

满足需求多样化,屏蔽使用差异,灵活、方便

总结

方法的重载我们只关注方法名和参数类型,要求方法名必须一致,参数列表必须不一致(个数,顺序,类型)

局部变量

概念

在方法内部或者形参列表上定义的变量(包括main方法)

作用域

从定义局部变量的那一行到所在的代码块结束

for (int i = 1; i <= 10; i++) {

}

for (int i = 1; i <= 10; i++) {

}

【注意】两个for循环中,i 循环变量分别属于不同的大括号以内,不同的作用域空间,并不冲突

生存期

从方法被调用的时刻算起到函数返回调用处的时刻结束

for (int i = 1; i <= 10; i++) {

}

System.out.println(i); // 报错,找不到符号

【注意】for 循环结束时局部变量 i 的生存期结束,在 for 循环外无法使用 i

单一性,不能重名

// 报错!
for (int i = 1; i <= 10; i++) {
    for (int i = 1; i <= 10; i++) {

    }
}

【注意】在一个方法内局部变量不能多次定义

值传递

class Test {
    public static void main(String[] args) {
        int num = 5;
        test(num);

        System.out.println(num);    // 5
    }

    public static void test(int num) {
        num = 10;
    }
}

【注意】基本数据类型作为参数传递给局部变量时,传递的是值,局部变量的更改不影响实参本身

javafangfa_引用传递
javafanggfa_值传递

引用传递

public class MethodDemoC {
    public static void main(String[] args) {
        int[] arr = new int[5];

        System.out.println("调用方法前:" + arr[0]);

        test(arr);

        System.out.println("调用方法后:" + arr[0]);
    }

    public static void test(int[] arr) {
        arr[0] = 1;
    }
}

【注意】引用数据类型传递时传递的是地址,局部变量直接作用于实参本身

引用传递分析图
More Actionsjavafangfa_引用传递

总结

  1. 局部变量声明在函数中,从定义的那一行开始到函数结束时被销毁
  2. 局部变量必须先赋值再使用
  3. 局部变量不能重复定义
  4. 值传递:基本数据类型的传递不改变实参
  5. 引用传递:引用数据类型的传递会改变实参
  6. Java中只有值传递,引用传递传递的是地址值

构造方法

引言

构造方法很重要,但是比较鸡肋

定义

构造方法(Constructor)的名称和类名相同,没有返回值类型。

作用

类中的特殊方法,用于创建对象,在创建对象的时候会执行一些初始化操作,如给成员属性赋初值

格式

格式:
    类名([参数...]){}
    Student(){}

注意:格式问题

1、构造方法的方法名与类名完全相同

2、构造方法没有返回值类型

3、创建对象时,触发构造方法的调用,不可手动调用

4、如果没有声明构造方法,编译器默认生成无参构造方法

5、如果定义了有参构造方法,编译器就不会创建无参构造方法

【强制要求】

无论什么时候,都要加上一个无参构造方法!!!

构造方法的使用

// 自定义有参构造方法,并给name属性赋值
Dog(String n) {
    name = n;
}

// 自定义无参构造方法
Dog(){}

构造方法的重载

public Dog(String n){
    name = n;
}

public Dog(String n, int i){
    name = n;
    age = i;
}

总结

  1. 构造方法是用来创建对象,在创建对象的过程中会进行初始化操作(为对象赋值)
  2. 构造方法也是方法,除了没有返回值,其他的都跟方法一样

按照方法参数列表的类型、个数、顺序去匹配,如果没有找到对应的就会报错

  1. 无论什么时候,都一定要给一个无参构造方法

扩展:反编译

javap -c -l -private 类名.class

扩展:对象的创建过程

1、类加载
2、内存中开辟对象空间
3、为各个属性赋予初始值
4、执行构造方法中的代码
5、将对象的地址赋值给变量

方法重写【@Override】

开发中父类的方法不一定适用于子类,因为父类方法不能更改,在子类中新增方法会造成代码的冗余,而且不符合逻辑

要求

  1. 应用于继承和实现接口
  2. 方法的返回值类型,方法名,形参列表与父类一致
  3. 使用@Override注解来标识
  4. 重写方法的访问修饰符权限不能低于父类
    private < 默认什么都不写什么都不写 < protected < public
/*
 *十二生肖类的继承+方法重写
 */
class rat {
    private String name;// 名字
    private int ranking;// 排名

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getRanking() {
        return ranking;
    }

    public void setRanking(int ranking) {
        this.ranking = ranking;
    }

    public void skill() {
        System.out.print("打洞");
    }

    public void print() {
        System.out.print(name + "\t" + ranking + "\t");
        skill();
        System.out.println();
    }
}

class cow extends rat {
    public void skill() {
        System.out.print("耕田");
    }
}

class tiger extends rat {
    public void skill() {
        System.out.print("打斗");
    }
}

class rabbit extends rat {
    public void skill() {
        System.out.print("躲避");
    }
}

class dragon extends rat {
    public void skill() {
        System.out.print("呼风唤雨");
    }
}

class snake extends rat {
    public void skill() {
        System.out.print("游走");
    }
}

class horse extends rat {
    public void skill() {
        System.out.print("飞奔");
    }
}

class sheep extends rat {
    public void skill() {
        System.out.print("吃草");
    }
}

class monkey extends rat {
    public void skill() {
        System.out.print("模仿");
    }
}

class chicken extends rat {
    public void skill() {
        System.out.print("啄食");
    }
}

class dog extends rat {
    public void skill() {
        System.out.print("游泳");
    }
}

class pig extends rat {
    public void skill() {
        System.out.print("吃");
    }
}

优点

既沿袭了父类的方法名,又实现了子类的扩展

总结

  1. 方法的重写能够在不新增方法的情况下实现子类的扩展
  2. 方法重写要求方法声明格式和父类完全一致(访问修饰符不能小于父类)
  3. @Overrid关键字用来开启格式检测,如果不一致就会报错

文章作者: 卢慧军
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 卢慧军 !
📣 评论
  目录
小程序