JAVA中关于方法的学习和扩展

方法:

一. 方法的引入,概述,格式,定义,调用,方法在内存中的执行原理

package com.sxt.methoddemo;

/*
 * 新的技术引入:
 * 	1.代码的简化
 *  2.代码的可读性
 *  3.代码的可维护性
 *  4.代码的可扩展性
 *  5.代码的安全性
 *  6.代码的效率
 *  7.用户体验 
 *  
 * 方法的引入
 * 	1.简化了代码
 *  2.提高了代码的可读性
 *  3.提高了代码维护性
 *  4.提高了代码扩展性
 *  
 * 概述: 完成特定功能的代码片段,通过数学意义上的函数引入的 y = f(x,y);
 * 
 * 格式:											
 * 	[访问权限修饰符] 返回值类型[输出的类型] 方法名(参数类型 变量名1, 参数类型 变量名2, ...) [throws 异常类名]{
 * 		方法体;
 * 		[return 返回值;]
 * 	}
 * 访问权限修饰符: 这里后面讲解面向对象的时候讲解,暂时使用 public static
 * 返回值类型: 这里可以是八大基本数据类型和引用数据类型,这里的类型和返回值对应类型满足类型转换 
 * 					类型转换: 
 * 							1.基本数据类型转换 【9种情况】
 * 							2.引用类型转换 【向上转型和向下转型】
 * 方法名: 满足方法名的命名规范,见名知意,一般是动词
 * 参数类型: 这里可以是八大基本数据类型和引用数据类型,这里传参同样满足类型转换 
 * 		形参: 方法定义的时候的参数
 * 		实参: 方法调用的时候的参数
 * 方法体: 功能代码
 * return:
 * 			单独使用: return; 表示直接退出当前所在的方法
 * 			带返回值使用 return 返回值; 这里的返回值类型和方法定义的返回值类型保持一致,或者满足类型转换
 * 			如果一个方法没有返回值,那么声明方法的时候返回值类型写void关键字
 * 			当一个方法声明了返回值类型,就必须显示使用return关键字返回结果给调用者
 * 
 * 方法定义的位置: 类体以内,方法体以外
 * 
 * 方法定义的三要素 (************************)
 * 1.参数列表 【输入】
 * 2.返回值类型 【输出】
 * 3.方法名 【调用】
 * 
 * 方法调用的三要素 (***********************)
 * 1.需要什么参数就给什么类型的参数
 * 2.返回什么类型的值就使用什么类型接收
 * 3.方法参数的个数类型顺序必须保持一致
 * 
 * 方法的调用方式
 * 1.直接调用 【适用于方法的返回值为void的情况】
 * 2.输出调用 【适用于方法的返回值后续不需要使用但需要输出的情况】
 * 3.赋值调用 【适用于方法的返回值后续还要继续使用的情况】
 * 
 * 需求: 计算m~n的和
 * 
 * 方法的注意事项:
 * 	1.方法不能够嵌套定义
 *  2.方法不调用不执行
 * 
 * 方法在内存中的执行原理
 * JVM的组成部分: 类加载器,运行时数据区,执行引擎, 本地接口
 * 
 * 我们重点关心: 运行时数据区
 * 运行时数据区划分:
 * 	栈
 * 	堆区
 * 	方法区
 * 	本地方法区
 * 	程序计数器
 */
public class MethodDemo01 {
	
	public static void main(String[] args) {
		getSum(1, 100);
		System.out.println(getSum(1, 100));
		int sum = getSum(1, 100);
		sum += 10;
		System.out.println(sum);
	}
	
	/*
	 * 1.参数列表 【输入】
	 * 		int m, int n
	 * 2.返回值类型 【输出】
	 * 		int 
	 * 3.方法名 【调用】
	 * 		getSum
	 */
	public static int getSum(int m, int n) {
		System.out.println("我被调用了...");
		int sum = 0;
		for (int i = m; i <= n; i++) {
			sum += i;
		}
		return sum;
	}
	
}

二. 方法运用例子。

package com.sxt.methoddemo;

import java.util.Scanner;

/*
 *  1、求两个数之和
 *	2、键盘录入年份判断是否是闰年
 *	3、键盘录入数据,返回两个数中的较大值
 *	4、判断一个数是否是素数
 *	5、打印m行n列的*型矩形
 *	6、打印九九乘法表
 */
public class MethodDemo02 {
	public static void main(String[] args) {
		// 输出调用
		System.out.println(add(5, 6));
		// 赋值调用
		Scanner input = new Scanner(System.in);
		System.out.print("请输入年份: ");
		// int year = input.nextInt();
		// boolean isLeapYear = isLeapYear(year);
		/*if (leapYear) {
			System.out.println("闰年");
		} else {
			System.out.println("不是闰年");
		}*/
		// System.out.println(isLeapYear(year) ? "是闰年" : "不是闰年");
		
		// 输出调用
		printRectangle(3, 7);
		
		System.out.println(isPrimeNumber(-6) ? "是素数": "不是素数");
		
		print99MulTable();
		
	}
	
	/*
	 * 功能: 求两个数之和
	 * 参数列表: int m, int n
	 * 返回值类型: int 
	 * 方法名: add
	 */
	public static int add(int m, int n) {
		/*int sum = 0;
		sum = m + n;*/
		return m + n;
	}
	
	/*
	 * 功能: 判断是否是闰年
	 * 参数列表: int year
	 * 返回值类型: boolean
	 * 方法名: isLeapYear
	 *  1、普通年能被4整除且不能被100整除的为闰年。(如2004年就是闰年,1900年不是闰年) 
	 *  2、世纪年能被400整除的是闰年。
	 */
	public static boolean isLeapYear(int year) {
		/*if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
			return true;
		} else {
			return false;
		}*/
		// boolean isLeapYear = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0) ? true : false;
		return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
	}
	
	/*
	 * 功能: 打印m行n列的*型矩形
	 * 参数列表: int row, int column
	 * 返回值类型: void
	 * 方法名: printRectangle 
	 */
	public static void printRectangle(int row, int column) {
		for (int i = 0; i < row; i++) {
			for (int j = 0; j < column; j++) {
				System.out.print("*");
			}
			System.out.println();
		}
	}
	
	/*
	 * 功能: 返回两个数中的较大值
	 * 参数列表: int m, int n
	 * 返回值类型: int
	 * 方法名: getMaxValue
	 */
	public static int getMaxValue(int m, int n) {
		/*int max = 0;
		if (m > n) {
			max = m;
		} else {
			max = n;
		}*/
		return m > n ? m : n;
	}
	
	/*
	 * 功能: 判断一个数是否是素数
	 * 参数列表: int num
	 * 返回值类型: boolean
	 * 方法名: isPrimeNumber
	 * 质数又称素数。指整数在一个大于1的自然数中,
	 * 除了1和此整数自身外,没法被其他自然数整除的数。
	 * 特点: 
	 * 	1.大于1的数
	 *  2.在2~该数-1的范围内,找不到任何因子能够被该数整除
	 *  
	 *  6 2~5
	 *  7 2~6
	 */
	public static boolean isPrimeNumber(int num) {
		// 默认是素数
		boolean flag = true;
		
		if (num < 1) {
			flag = false;
		} else {
			// 遍历该数的每一个因子
			for (int i = 2; i <= num-1; i++) {
				if (num % i == 0) {
					flag = false;
					break;
				}
			}
		}
		return flag;
	}
	/*
	 * 功能: 打印九九乘法表
	 * 参数列表: 无参
	 * 返回值类型: void
	 * 方法名: print99MulTable
	 */
	public static void print99MulTable() {
		for (int i = 1; i <= 9; i++) {
			for (int j = 1; j <= i; j++) {
				System.out.print(j + "x" + i + "=" + (i*j) + "\t");
			}
			System.out.println();
		}
	}
	
}

三. 常见错误和注意事项。

调用方法时不能指定实参类型
形参和实参数据类型不一致
形参和实参个数不一致
方法不调用不执行
方法不能嵌套定义
参数传递一样满足数据类型的转换
如果方法在定义的时候有返回值,那么在方法中一定要有return关键字返回数据给调用者
为了在书写方法的时候避免程序报错,可以优先写好返回值,如返回整型,就return 0


方法的重载:

package com.sxt.methoddemo;

import java.util.Arrays;

/*
 * 为什么需要学习方法重载? 
 * - 解决多个方法的参数不同但是方法功能相同的重名问题
 * - 简化代码,提高了扩展性和维护性
 * 
 * 概述: 发生在同一个类中,方法的名称相同,参数列表不同构成重载
 * 
 * 特点:
 * 	1.发生在同一个类中
 *  2.方法名称相同
 *  3.参数的个数,顺序,类型不同都可以构成重载 【Overload】
 *  	1和2 顺序不同构成重载
 *  	3和4 个数不同构成重载
 *  	2和3 类型不同构成重载
 *  4.方法重载和返回值类型以及访问权限修饰符毫无关系,但是重写有关系
 *  5.在方法调用的时候满足精确性原则和准确性原则
 *  6.方法重载也是多态的一种表现形式 (后面讲解面向对象讲解)
 */
public class MethodDemo03 {
	public static void main(String[] args) {
		// add(2.5, 10);
		// add(10, 20);
	}
	
	// 计算一个小数和一个整数的和 1
	public static double add(int a, double b) {
		System.out.println("x");
		return a + b;
	}
	
	public static double add(int a, byte b) {
		System.out.println("y");
		return a + b;
	}
	
	// 2
	public static double add(double a, int b) {
		System.out.println("2");
		return a + b;
	}
	
	// 2.5
	public static double add(double a, double b) {
		System.out.println("2.5");
		return a + b;
	}
	
	// 计算两个整数的和
	// 3
	/*public static double add(int a, int b) {
		return a + b;
	}*/
	
	// 计算三个整数的和
	// 4
	public static double add(int a, int b, int c) {
		return a + b + c;
	}
	
}
class B {
	public static double add(int a, int b, int c) {
		return a + b + c;
	}
}

方法递归:

package com.sxt.methoddemo;

/*
 * 方法递归
 * 
 * 为什么需要学习方法递归?
 * 1.可读性提高
 * 2.简化代码
 * 3.常用于文件夹遍历,通讯录的制作,层级菜单
 * 
 * 递归:本质就是对自身回路的重复
 * 递归在Java是通过方法实现的,就是方法中调用方法自己本身
 * 
 * 1.递归必须要有出口,否则会出现死递归
 * 2、递归的次数太多很容易出现内存溢出。
 * 3、构造方法不能递归。
 * 
 * 死递归和死循环的区别   可以有死循环,不可以有死递归
 */
public class MethodDemo04 {
	public static void main(String[] args) {
//		System.out.println("我是主方法");
//		main(new String[] {});
		diGuiTellStory(10);
	}
	
	// 递归讲故事  老和尚和小和尚的故事
	public static void diGuiTellStory(int i) {
		
		if (i == 0) {
			return;
		}
		
		System.out.println("从前有座山,山里有座庙,庙里有个老和尚和小和尚,"
				+ "老和尚对小和尚说: 故事是: " + i);
		diGuiTellStory(--i);
	}
}

递归应用例子:

package com.sxt.methoddemo;

/*
 * 递归求5的阶乘以及斐波那契数列
 * 5 * 4 * 3 * 2 * 1
 */
public class MethodDemo05 {
	public static void main(String[] args) {
		System.out.println(getJieChengByLoop(5));
		System.out.println(getJieChengByDiGui(5));
		System.out.println(fiboonaqi(4));
	}
	
	public static long getJieChengByLoop(int num) {
		long jc = 1;
		for (int i = 1; i <= num; i++) {
			jc *= i;
		}
		return jc;
	}
	
	/*
	 * 120
	 * 		return 5 * 24
	 * 						return 4 * 6
	 * 										return 3 * 2
	 * 														return 2 * 1
	 * 																			return 1
	 * 			
	 */
	public static long getJieChengByDiGui(int num) {
		if (num <= 0) {
			return 0;
		}
		
		// 先确定出口
		if (num == 1) {
			return 1;
		}
		
		return num * getJieChengByDiGui(--num);
	}
	
	/*
	 * 1、1、2、3、5、8、13、21、34
	 * 从第三项开始,数值等于前两项的和
	 */
	public static int fiboonaqi(int n) {
		
		if (n <= 0) {
			return 0;
		}
		
		// 先确定出口
		if (n == 1 || n == 2) {
			return 1;
		}
		
		return fiboonaqi(n - 1) + fiboonaqi(n - 2);
	}
}