1 - 方法的重载(over load)
/*
* 1-方法的重载(over load)
* ①概念:在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
* ②特点:与返回值类型无关,只看参数列表,且参数列表必须不同(参数个数或参数类型)。调用时,根据方法参数列表的不同来区别。
*
* ③总结:"两同一不同" 即同一个类,相同的方法名。参数列表不同:参数个数不同,参数类型不同。
*
* 2-判断是否是重载:跟方法的权限修饰符,返回值类型,形参变量名,方法体都没有关系。
*
* 3-在通过对象调用方法时,如何确定某一个指定的方法:方法名 --> 参数列表
*
*/
代码示例(如下两个同名方法就够成方法重载)
//以下示例就叫做方法重载//反转数组1(int[])
public void reverseArray(int[] array){for(int i = 0;i < array.length / 2;i++){int temp =array[i];
array[i]= array[array.length - i - 1];
array[array.length- i - 1] =temp;
}
}//反转数组2(String[])
public voidreverseArray(String[] array){
}//注意看它们的方法名和参数
练习题
/** 1-编写程序,定义三个重载方法并调用。方法名为mOL。三个方法分别接收一个int参
数、两个int参数、一个字符串。
* 分别执行平方运算并输出结果,相乘并输出结果,输出字符串信息,在主类的main()方法中分别用参数区别调用三个方法。
*
* 2-定义三个重载方法max(),
* 第一个方法求两个int值中的最大值,
* 第二方法求两个double值中的最大值,
* 第三个方法求三个double值的最大值,
* 并分别调用三个方法*/
public classOverLoadTest {public static voidmain(String[] args) {//TODO Auto-generated method stub
OverLoadTest load = newOverLoadTest();
load.mOL(5);
load.mOL(4, 5);
load.mOL("hello world");double res1 = load.max(1.0, 2.0);
System.out.println(res1);double res2 = load.max(20, 30);
System.out.println(res2);double res3 = load.max(1, 2, 3);
System.out.println(res3);
}//1.如下三个方法构成重载
public void mOL(inti) {
System.out.println(i*i);
}public void mOL(int j,inti) {
System.out.println(j*i);
}public voidmOL(String s) {
System.out.println(s);
}//2.如下三个方法构成重载
public int max(int i,intj) {//if(i > j) {//return i;//}else {//return j;//}
return (i > j)?i : j;
}public double max(double i,doublej) {return (i > j)?i : j;
}public double max(double d1,double d2,doubled3) {double max = (d1 > d2)?d1 : d2;return (max > d3)?max : d3;
}
}
方法重载练习
2 - 可变个数的形参
JavaSE 5.0 中提供了Varargs(variable number of arguments)机制,允许直接定 义能和多个实参相匹配的形参。从而,可以用一种更简单的方式,来传递个数可 变的实参。
//JDK 5.0以前:采用数组形参来定义方法,传入多个同一类型变量 public static void test(int a ,String[] books);
//JDK5.0:采用可变个数形参来定义方法,传入多个同一类型变量 public static void test(int a ,String…books);
/*
* 可变个数形参的方法
* 1-jdk 5.0新增的内容
* 2-具体使用
* ①可变个数形参的格式:数据类型 ... 变量名
* ②当调用可变个数形参的方法时,传入的参数个数可以是:0个,1个,2个,或多个 ...
* ③可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载
* ④可变个数形参的方法与本类中方法名相同,形参类型也相同的数组之间不构成重载,换句话说,二者不能共存。
* ⑤可变个数形参在方法的形参中,必须声明在末尾。
* ⑥可变个数形参在方法的形参中,最多只能声明一个可变形参。
*/
public classMethodArgsTest {public static voidmain(String[] args) {//TODO Auto-generated method stub
}public void show(inti) {
}public voidshow(String s) {
}public voidshow(String ... strs) {
}
}
3-具体使用代码示例
public classMethodArgsTest {public static voidmain(String[] args) {//TODO Auto-generated method stub
MethodArgsTest test = newMethodArgsTest();
test.show(1);
test.show("hello world");
test.show("hello","world");
test.show();
}public void show(inti){
}public voidshow(String s){
System.out.println(s);
}public voidshow(String ... strings){//System.out.println("执行可变个数形参方法 ...");
for(int i = 0;i < strings.length;i++){
System.out.print(strings[i]+"\t");
}
System.out.println();
}//public void show(String[] args){//System.out.println("");//}//调用时:test.show(new String[]{"aa","bb"});
public void show(inti,String ... strings){//可变个数形参,必须声明在末尾,且最多只能声明一个。
}
}
可变个数形参
3 - 方法参数的值传递机制
1 方法,必须由其所在类或对象调用才有意义。若方法含有参数:
✔ 形参:方法声明时的参数
✔ 实参:方法调用时实际传给形参的参数值
2 Java的实参值如何传入方法呢?
Java里方法的参数传递方式只有一种:值传递。 即将实际参数值的副本 (复制品)传入方法内,而参数本身不受影响。
✔ 形参是基本数据类型:将实参基本数据类型变量的“数据值”传递给形参
✔ 形参是引用数据类型:将实参引用数据类型变量的“地址值”传递给形参
1-关于变量的赋值
/** 关于变量的赋值
* 1-如果变量是基本数据类型,此时赋值的是变量所保存的数据值。
* 2-如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值*/
public classValueTransferTest {public static voidmain(String[] args) {//基本数据类型之局部变量赋值
int m = 20;int n =m;
System.out.println("m="+m+", n="+n);
n= 10;
System.out.println("m="+m+", n="+n);//引用数据类型
Order order1 = newOrder();
order1.orderId= 50;
Order order2= order1; //order1 和 order2 的地址值相同,都指向了堆空间中的同一个实体
System.out.println("order1.Id="+order1.orderId+"\norder2.Id="+order2.orderId);
order2.orderId= 100;
System.out.println("order1.Id="+order1.orderId+"\norder2.Id="+order2.orderId);
}
}classOrder{intorderId;
}
基本数据类型和引用数据类型的赋值
2-方法参数的值传递机制
/** 方法的形参的传递机制:值传递
* 1-形参:方法定义时,声明的小括号内的参数
* 2-实参:方法调用时,实际传递给形参的数据
*
* 3-值传递机制
* 如果形参是基本数据类型,此时实参赋给形参的是实参真实存储的数据值。
* 如果参数是引用数据类型,此时赋值的是变量所保存的数据的地址值。*/
public classValueFransferTest {public static voidmain(String[] args) {//交换两个变量的值操作
int m = 10;int n = 20;
System.out.println("交换前:m="+m+"\tn="+n); //交换前:m=10 n=20//int temp = m;//m = n;//n = temp;
ValueFransferTest test = newValueFransferTest();
test.swap(m,n);
System.out.println("交换后:m="+m+"\tn="+n); //交换后:m=10 n=20
}public void swap(int m,intn) {int temp =m;
m=n;
n=temp;
}
}
值传递机制
图解
3-在声明的方法中实现 m 和 n 的值交换
public classValueTransferTest {public static voidmain(String[] args) {
Data data= newData();
data.m= 10;
data.n= 20;
System.out.println("交换前:m="+data.m+"\tn="+data.n);//交换 m 和 n 的值//int temp = data.m;//data.m = data.n;//data.n = temp;
ValueTransferTest test = newValueTransferTest();
test.swap(data);
System.out.println("交换后:m="+data.m+"\tn="+data.n);
}public voidswap(Data data){int temp =data.m;
data.m=data.n;
data.n=temp;
}
}classData{intm;intn;
}
在声明的方法中实现交换
图解
4-值传递机制总结(重点)
/*
* 如果形参是基本数据类型,此时实参赋给形参的是实参真实存储的数据值。
* 如果参数是引用数据类型,此时赋值的是变量所保存的数据的地址值。
*/
4 - 面试题
/** 面试题:
* 定义一个int型的数组,int[] arr = new int[]{12,3,3,34,56,77,43}; 让数组的每个位置上的值去除 以首位置的元素
* 得到的结果,作为该位置上的新值,遍历新的数组*/
public classValueFransferTest {public static voidmain(String[] args) {int[] arr = new int[] {12,3,3,34,56,77,43};//写法1//for(int i = arr.length - 1;i >= 0;i--) {//arr[i] = arr[i] / arr[0];//}//写法2
int temp = arr[0];for(int i = 0;i < arr.length;i++) {
arr[i]= arr[i] /temp;
System.out.println(arr[i]);
}
}
}
5 - 值传递机制练习
1-题目
/*
* 1-定义一个Circle类,包含一个double型的radius属性代表圆的半径
* 一个findArea()方法返回圆的面积
*
* 2-定义一个类PassObject,在 类中定义一个方法printAreas(),
* 该方法的定义如下:public void printAreas(Circle c,int time)
* 在printAreas方法中打印输出1到time之间的每个整数半径值,以及对应的面积
* 例如,times为5,则输出半径1,2,3,4,5,以及对应的圆面积。
* 在main方法中调用printAreas()方法,调用完毕后输出当前半径值。
*/
2-在 Circle.java 文件中
/** 定义一个Circle类,包含一个double型的radius属性代表圆的半径
* 一个findArea()方法返回圆的面积*/
public classCircle {double radius; //半径//求圆的面积
public doublefindArea(){return Math.PI * radius *radius;
}
}
Circle.java
3- 在 PassObject.java 文件中
/**
* 2-定义一个类PassObject,在 类中定义一个方法printAreas(),
* 该方法的定义如下:public void printAreas(Circle c,int time)
* 在printAreas方法中打印输出1到time之间的每个整数半径值,以及对应的面积
* 例如,times为5,则输出半径1,2,3,4,5,以及对应的圆面积。
* 在main方法中调用printAreas()方法,调用完毕后输出当前半径值。*/
public classPassObject {public static voidmain(String[] args) {
PassObject test= newPassObject();
test.printAreas(new Circle(),5);
}public void printAreas(Circle c,inttime){
System.out.println("Radius\t\tAreas");for(int i = 1;i <= time;i++){
c.radius=i;
System.out.println(c.radius+"\t\t"+c.findArea());
}
}
}
PassObject.java
6 - 递归(recursion)方法
/** 1-递归方法:一个方法体内调用它本身
* 2-方法递归包含了一种隐式的循环,它会重复执行某段代码,单这种重复执行无须循环控制
* 3-递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环。*/
public classRecursionTest {public static voidmain(String[] args) {//例题:计算1-100之间所有自然数之和//方式1
int sum = 0;for(int i =0;i <= 100;i++) {
sum+=i;
}
System.out.println(sum);//方式2
RecursionTest test = newRecursionTest();int res = test.getSum(100);
System.out.println(res);
}//方式2
public int getSum(intn) {if(n == 1) {return 1;
}else{return n + getSum(n - 1);
}
}
}
经典例题:斐波那契数列
/** 输入一个数据n,计算斐波那契数列(Fibonacci)的第n个值 1 1 2 3 5 8 13 21 34 55
* 规律:一个数等于前两个数之和
* 要求:计算斐波那契(Fibonacci)的第n个值,并将整个数列打印出来*/
public classFibonacciTest {public static voidmain(String[] args) {//递归方法
FibonacciTest test = newFibonacciTest();int res = test.Fibonacci(10);
System.out.println(res);
}public int Fibonacci(intn) {//出口
if((n <= 2)) {return 1;
}return Fibonacci(n - 1) + Fibonacci(n - 2);
}
}
递归与斐波那契数列
总结递归的使用
1. 必须有一个明确的结束条件
2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出