博客园 首页 私信博主 显示目录 隐藏目录 管理

Java方法

Java方法

定义

Java方法是语句的集合,他们在一起执行一个功能

  • 方法是解决一类问题步骤的有序集合
  • 方法包含与类或对象中
  • 方法在程序中被创建,在其他地方被引用

方法包含一个方法头和一个方法体

  • 修饰符:这个是可选的,告诉编译器如何调用该方法,定义了该方法的访问类型

  • 返回值类型:方法可能存在返回值,return Value Type是方法返回值的数据类型,有些方法执行所需的操作,但没有返回值,这种情况下,返回值的类型为void

  • 方法名:是方法的实际名称,方法和参数表共同构成方法签名

  • 参数类型:参数像是一个占位符,当方法被调用时,传递值给参数,这个值称之为实参或变量,参数列表是指方法的参数类型,顺序和参数个数,参数是可选的,方法可以不包含任何参数

    • 形式参数:方法被调用时用于接收外界输入的数据

    • 实参:方法调用时实际传递给方法的数据

      public static void main(String[] args) {
          //这里的1,2是实际参数
          int num = add(1, 2);
      }
      //这里的a,b是形式参数
      public static int add(int a,int b){
          return a + b;
      }
      
  • 方法体:方法体包含具体的语句,定义该方法的功能

设计方法的原则

方法的本意是功能块,就是实现某个功能的语句块集合。我们设计方法的时候,最好保持方法的原子性,就是一个方法只完成一个功能,这样利于后期的扩展

方法的重写与重载
方法的重写(Override)
  • 重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!

  • 重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。

  • 重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。例如: 父类的一个方法申明了一个检查异常 IOException,但是在重写这个方法的时候不能抛出 Exception 异常,因为 Exception 是 IOException 的父类,只能抛出 IOException 的子类异常。

  • 在面向对象原则里,重写意味着可以重写任何现有方法。

方法重写的规则

  • 参数列表与被重写方法的参数列表必须完全相同。
  • 返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类(java5 及更早版本返回类型要一样,java7 及更高版本可以不同)。
  • 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为 public,那么在子类中重写该方法就不能声明为 protected。
  • 父类的成员方法只能被它的子类重写。
  • 声明为 final 的方法不能被重写。
  • 声明为 static 的方法不能被重写,但是能够被再次声明。
  • 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法。
  • 子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。
  • 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
  • 构造方法不能被重写。
  • 如果不能继承一个类,则不能重写该类的方法。

super关键字的使用

当需要在子类中调用父类的被重写方法时,要使用 super 关键字。

class Animal{
   public void move(){
      System.out.println("动物可以移动");
   }
}
 
class Dog extends Animal{
   public void move(){
      super.move(); // 应用super类的方法
      System.out.println("狗可以跑和走");
   }
}
 
public class TestDog{
   public static void main(String args[]){
 
      Animal b = new Dog(); // Dog 对象
      b.move(); //执行 Dog类的方法
 
   }
}
方法的重载(overload)

重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。

每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。

最常用的地方就是构造器的重载。

重载规则:

  • 被重载的方法必须改变参数列表(参数个数或类型不一样);
  • 被重载的方法可以改变返回类型;
  • 被重载的方法可以改变访问修饰符;
  • 被重载的方法可以声明新的或更广的检查异常;
  • 方法能够在同一个类中或者在一个子类中被重载。
  • 无法以返回值类型作为重载函数的区分标准。

扩展
值传递和引用传递

1、按值传递:值传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。简单来说就是直接复制了一份数据过去,因为是直接复制,所以这种方式在传递时如果数据量非常大的话,运行效率自然就变低了,所以Java在传递数据量很小的数据是值传递,比如Java中的各种基本类型:int,float,double,boolean等类型的,具体可以自己测试。

2、按引用传递:引用传递其实就弥补了上面说的不足,如果每次传参数的时候都复制一份的话,如果这个参数占用的内存空间太大的话,运行效率会很底下,所以引用传递就是直接把内存地址传过去,也就是说引用传递时,操作的其实都是源数据,这样的话修改有时候会冲突,记得用逻辑弥补下就好了,具体的数据类型就比较多了,比如Object,二维数组,List,Map等除了基本类型的参数都是引用传递。

public static void main(String[] args) {
    int num = 100;
    add(num);
    System.out.println(num);
    Student student = new Student();
    student.setName("zhangsan");
    add(student);
    System.out.println(student.getName());
}
public static void add(int a){
    ++a;
}
public static void add(Student stu){
    stu.setName("lisi");
}

结果:

100
lisi
递归

就是方法的方法体中存在调用自身的情况

案例:

斐波那契数列

public static void main(String[] args) {
	int i = 1;
	for (i = 1; i <= 20; i++) {
		System.out.println("兔子第" + i + "个月的总数为:" + f(i));
	}
}
public static int f(int x) {
	if (x == 1 || x == 2) {
		return 1;
	} else {
		return f(x - 1) + f(x - 2);
	}
}

归并排序算法实现

package com.luna.base;
public class MergingSort {    
    public static void sort(int[] data, int left, int right) {    
        if (left < right) {    
            // 首先找出中间的索引    
            int center = (left + right) / 2;    
    
            // 对中间索引左边的数组进行递归    
            sort(data, left, center);    
    
            // 对中间索引右边的数组进行递归    
            sort(data, center + 1, right);    
            // 合并    
            merge(data, left, center, right);    
        }    
    }    
    
    public static void merge(int[] data, int left, int center, int right) {    
        int[] tmpArr = new int[data.length];        
        int mid = center + 1;      
        // third记录中间数组的索引    
        int third = left;    
        int tmp = left;        
        while (left <= center && mid <= right) {    
            // 将两个数组中取出最小的数放入中间数组    
            if (data[left] <= data[mid]) {    
                tmpArr[third++] = data[left++];    
            } else {    
                tmpArr[third++] = data[mid++];    
            }    
        }    
    
        // 剩余部分依次放入中间数组    
        while (mid <= right) {    
            tmpArr[third++] = data[mid++];    
        }       
        while (left <= center) {    
            tmpArr[third++] = data[left++];    
        }                
        while(tmp <= right){    
            data[tmp] = tmpArr[tmp++];    
        }    
    }    
    
    public static void main(String[] args) {    
        int[] a = { 3, 2, 5, 4 };               
        sort(a, 0, a.length - 1);        
        for (int i = 0; i < a.length; i++) {    
            System.out.print(a[i] + " ");    
        }    
    }    
}  
可变参数

在方法声明中,在指定参数类型后加一个省略号(...)

一个方法中只能指定一个可变参数,她必须是方法的最后一个参数,任何普通参数都必须在她之前声明

public static void main(String[] args) {
    add(1,2,3);
}
public static void add(int... a){
    System.out.println(a[0]);
    System.out.println(a[1]);
    System.out.println(a[2]);
}
posted @ 2021-05-05 18:42  莫逆追风  阅读(31)  评论(0)    收藏  举报