Java语言程序设计(基础篇) 第六章 方法
第六章 方法
6.2 定义方法
1.方法的定义由方法名称、参数、返回值类型以及方法体组成。
2.定义在方法头中的变量称为形式参数(formal parameter)或者简称为形参(parameter)。参数就像占位符。当调用方法时,就给参数传递一个值,这个值称为实际参数(actual parameter)或实参(argument)。参数列表(parameter list)指明方法中参数的类型、顺序和个数。方法名和参数列表一起构成方法签名(method signature)。参数是可选的,也就是说,方法可以不包含参数。
3.带返回值的方法称为函数,返回值类型为void的方法称为过程。
6.8 重载方法
1.重载方法使得你可以使用同样的名字来定义不同方法,只要它们的签名是不同的。
2.重载方法可以使得程序更加清楚,以及更加具有可读性。执行同样功能但是具有不同参数类型的方法应该使用同样的名字。
3.被重载的方法必须具有不同的参数列表。不能基于不同修饰符或返回值类型来重载方法。
4.有时调用一个方法时,会有两个或更多的可能,但是,编译器无法判断哪个是最精确的匹配。这称为歧义调用(ambiguous invocation)。歧义调用会产生一个编译错误。
1 package com.chapter6; 2 3 public class TestMethodOverloading { 4 5 /** 6 * 方法重载: 7 * 1.第一个方法求最大整数; 8 * 2.第二个方法求最大双精度数; 9 * 3.第三个方法求三个双精度数中的最大值。 10 */ 11 12 public static void main(String[] args) { 13 14 System.out.println("比较3和4:"+max(3,4)); 15 16 System.out.println("比较3.0和5.4:"+max(3.0,5.4)); 17 18 System.out.println("比较3.0,5.4,10.14:"+max(3.0,5.4,10.14)); 19 20 } 21 22 public static int max(int num1,int num2){ 23 if(num1>num2){ 24 return num1; 25 }else{ 26 return num2; 27 } 28 } 29 30 public static double max(double num1,double num2){ 31 if(num1>num2){ 32 return num1; 33 }else{ 34 return num2; 35 } 36 } 37 38 public static double max(double num1,double num2,double num3){ 39 return max(max(num1,num2),num3); 40 } 41 42 }
6.9 变量的作用域
1.变量的作用域(scope of a variable)是指变量可以在程序中引用的范围。
2.在方法中定义的变量称为局部变量(local variable)。局部变量的作用域从声明变量的地方开始,直到包含该变量的块结束为止。局部变量都必须在使用之前进行声明和赋值。
3.不要在块内声明一个变量然后企图在块外使用它,下面是一个常见错误的例子:
for(int i=0;i<10;i++){
}
System.out.println(i);
6.11方法抽象和逐步求精
1 package com.chapter6; 2 3 import java.util.Scanner; 4 5 public class PrintCalendar { 6 7 /** 8 * 打印日历 9 */ 10 11 public static void main(String[] args) { 12 13 Scanner input = new Scanner(System.in); 14 15 System.out.println("请输入一个年份(例如:2016):"); 16 int year = input.nextInt(); 17 18 System.out.println("请输入一个月份(1-12):"); 19 int month = input.nextInt(); 20 21 printMonth(year, month); 22 23 } 24 25 // 打印日历方法 26 public static void printMonth(int year, int month) { 27 28 printMonthTitle(year, month);// 打印日历的标题 29 30 printMonthBody(year, month);// 打印日历的主体 31 } 32 33 // 打印日历标题的方法:年月,虚线,每周七天的星期名称 34 public static void printMonthTitle(int year, int month) { 35 36 System.out.println(" " + getMonthName(month) + " " + year); 37 System.out.println("-------------------------------------------"); 38 System.out.println(" Sun Mon Tue Wed Thu Fri Sat"); 39 40 } 41 42 // 获得每个月的名字 43 public static String getMonthName(int month) { 44 String monthName = ""; 45 switch (month) { 46 case 1: 47 monthName = "January"; 48 break;// 一月 49 case 2: 50 monthName = "February"; 51 break;// 二月 52 case 3: 53 monthName = "March"; 54 break;// 三月 55 case 4: 56 monthName = "April"; 57 break;// 四月 58 case 5: 59 monthName = "May"; 60 break;// 五月 61 case 6: 62 monthName = "June"; 63 break;// 六月 64 case 7: 65 monthName = "July"; 66 break;// 七月 67 case 8: 68 monthName = "August"; 69 break;// 八月 70 case 9: 71 monthName = "September"; 72 break;// 九月 73 case 10: 74 monthName = "October"; 75 break;// 十月 76 case 11: 77 monthName = "November"; 78 break;// 十一月 79 case 12: 80 monthName = "December"; 81 break;// 十二月 82 } 83 return monthName; 84 } 85 86 // 打印日历的主体 87 public static void printMonthBody(int year, int month) { 88 89 int startDay = getStartDay(year, month);//getStartDay(year, month)这个月的第一天是星期几 90 91 int numberOfDaysInMonth = getNumberOfDaysInMonth(year, month);//getNumberOfDaysInMonth(year, month)这个月有多少天 92 93 int i = 0; 94 for (i = 0; i < startDay; i++) { 95 System.out.print(" "); 96 } 97 for (i = 1; i <=numberOfDaysInMonth; i++) { 98 System.out.printf("%5d", i); 99 if ((i + startDay) % 7 == 0) { 100 System.out.println(); 101 } 102 } 103 System.out.println(); 104 } 105 106 // 这个月的第一天是星期几 107 /* 108 * 假设知道1800年1月1日是星期三(START_DAY_FOR_JAN_1_1800 = 3),然后然后计算1800年1月1日和日历月份的第一天之间相差的总天数(totalNumberOfDays)。 109 * 因为每个星期有7天,所以日历月份第一天的星期就是(totalNumberOfDays+START_DAY_FOR_JAN_1_1800)%7。 110 */ 111 public static int getStartDay(int year, int month) { 112 113 final int START_DAY_FOR_JAN_1_1800 = 3; 114 115 int totalNumberOfDays = getTotalNumberOfDays(year, month); 116 117 return (totalNumberOfDays + START_DAY_FOR_JAN_1_1800) % 7; 118 } 119 120 //获取1800年1月1日和日历月份的第一天之间相差的总天数 121 public static int getTotalNumberOfDays(int year, int month) { 122 123 int total = 0; 124 125 for (int i = 1800; i < year; i++) { 126 if (isLeapYear(i)) { 127 total = total + 366; 128 } else { 129 total = total + 365; 130 } 131 } 132 133 for (int i = 1; i < month; i++) { 134 total = total + getNumberOfDaysInMonth(year, i); 135 } 136 137 return total; 138 } 139 140 //计算总天数,需要知道该年是否是闰年以及每个月的天数 141 public static int getNumberOfDaysInMonth(int year, int month) { 142 143 if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) { 144 return 31; 145 } 146 147 if (month == 4 || month == 6 || month == 9 || month == 11) { 148 return 30; 149 } 150 151 if (month == 2) { 152 return isLeapYear(year) ? 29 : 28;//二月通常有28天,但是在闰年有29天 153 } 154 155 return 0; 156 157 } 158 159 //判断该年是否为闰年 160 public static boolean isLeapYear(int year) { 161 return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0); 162 } 163 164 }