1.方法
????????方法就是一段用来完成特定功能的代码片段,类似于其他语言的函数。
方法用于定义该类或该类的实例的行为特征和功能实现。方法是类和对象行为特征的抽象。
方法类似于面向过程中函数,在面向过程中,函数是最基本的单位,整个程序由一个个函数调用组成。在面向对象编程中,整个程序的基本单位是类,方法是从属于类和对象的。?
方法声明格式:
[修饰符1 修饰符2…] 返回值类型 方法名(形式参数列表){
? ? ? ? Java语句;…… }? ? ??
方法的调用方式:
对象名.方法名(实参列表)
方法的详细说明:
- 形式参数:在方法声明时用于接收外界传入的数据,简称形参。
- 实参:调用方法时,实际传给方法的数据。
- 返回值:方法执行完毕后,返回给调用它的环境的数据。
- 返回值类型:事先约定的返回值的数据类型。如无返回值,必须显示指定其为void。
package chap3_方法;
/**
* 方法的声明及调用
*/
public class Test01 {
public static void main(String[] args) {
int num1 = 10;
int num2 = 20;
//调用求和的方法:将num1与num2的值传给add方法中的n1与n2
//求完和后将结果返回,用sum接收结果
int sum = add(num1,num2);
System.out.println("sum="+sum); //输出:sum=30
//调用打印的方法:该方法没有返回值
print();
}
/*求和的方法*/
public static int add(int n1,int n2){
int sum = n1 + n2;
return sum;//使用return返回计算的结果 //结束方法
}
/*打印的方法*/
public static void print(){
System.out.println("再小的船也能远航...");
}
}
注意事项:
- 实参的数目、数据类型和次序必须和所调用的方法声明的形式参数列表匹配。
- 注意return语句终止方法的运行并指定要返回的数据。
- Java在方法调用中传递参数时,遵循值传递的原则(传递的都是数据的副本):
- 基本类型传递的是该数据值的copy值。
- 引用类型传递的是该对象引用的copy值,但指向的是同一个对象。
2.方法的重载
? ? ? ? 方法的重载(overload)是指一个类中可以定义多个方法名相同,但参数不同的方法。调用时,会根据不同的参数自动匹配对应的方法。
菜鸟雷区:重载的方法,实际是完全不同的方法,只是名称相同而已。
构成方法重载的条件如下:
- 不同的含义:形参类型、形参个数、形参顺序不同。
- 只有返回值不同不构成方法的重载,如int a(String str){ }与void a (String str){ }不构成方法重载。
- 只有形参的名称不同,不构成方法的重载,如int a(String str){ }与int a(String s){ }不构成方法的重载。
package chap3_方法;
/**
* 方法重载
*/
public class Test02 {
public static void main(String[] args) {
int sum = add(3,5);
System.out.println(sum); //8
System.out.println(add(3,5,10)); //18
System.out.println(add(3.0,5)); //8.0
System.out.println(add(3,5.0)); //8.0
System.out.println(); //0个参数
System.out.println(1); //参数是一个int
System.out.println(3.0); //参数是一个double
}
/*求和的方法*/
public static int add(int n1,int n2){
int sum = n1 + n2;
return sum;
}
//方法名相同,参数个数不同,构成重载
public static int add(int n1,int n2,int n3){
int sum = n1 + n2 + n3;
return sum;
}
//方法名相同,参数类型不同,构成重载
public static double add(double n1,int n2){
double sum = n1 + n2;
return sum;
}
//方法名相同,参数顺序不同,构成重载
public static double add(int n1,double n2){
double sum = n1 + n2;
return sum;
}
//编译错误:只有返回值不同,不构成方法的重载
public static double add(int n1,int n2){
double sum = n1 + n2;
return sum;
}
//编译错误:只有参数名称不同,不构成方法的重载
public static int add(int n2,int n1){
double sum = n1 + n2;
return sum;
}
}
3.命令行传递参数
? ? ? ? 有时候希望运行一个程序时候再传递给它消息,这要靠传递命令行参数给main()实现。
package com.RJ.chap;
public class Test03 {
public static void main(String[] args) {
for (int i = 0; i < args.length; i++) {
System.out.println("args["+i+ "]:" + args[i]);
}
}
}
进入当前dos环境下通过javac进行编译Test
javac Test.java
会在当前目录下生成一个Test.class文件,但是不能直接Java Test去执行,错误信息: 找不到或无法加载主类 Test,这是因为Test有相应的包com.RJ.chap(注:想要命令行传递参数,包名不能含中文)。这时就需要回退到src目录下(返回上一级cd..或cd../),现在再去执行,要写它的全路径
java com.RJ.chap.Test
现在给它传递一个参数this is kuangstudy(注:须在参数前写上它的全路径java com.RJ.chap.Test)
java com.RJ.chap.Test this is kuangstudy
执行后就会打印出来,如下
4.可变参数(不定项参数)
- JDK1.5开始,Java支持传递同类型的可变参数给一个方法。
- 在方法声明中,在指定参数类型后加一个省略号(...)。
- 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。
package chap3_方法;
/**
* 可变参数(不定项参数)
*/
public class Test03 {
public static void main(String[] args) {
Test03 test03 = new Test03();
test03.test(1,2,3);
}
public void test(int... i){
System.out.println(i[0]); // 1
System.out.println(i[1]); // 2
System.out.println(i[2]); //3
}
}
package chap3_方法;
/**
* 可变参数(排序)
*/
public class Test04 {
public static void main(String[] args) {
prinMax(3,0,3);//3.0
prinMax(9.2,8);//9.2
}
public static void prinMax(double... numbers){
if (numbers.length == 0){
System.out.println("没有传递任何参数!");
return;
}
double result = numbers[0];
//排序
for (int i=1; i < numbers.length;i++){
if (numbers[i] > result){
result = numbers[i];
}
}
System.out.println("The max value is:" + result);
}
}
5.递归结构
? ? ? ? 递归是一种常见的解决问题的方法,即把问题逐渐简单化。递归的基本思想“自己调用自己”,一个使用递归技术的方法将会直接或间接地调用自己。
? ? ? ? 利用递归可以用简单地程序来解决一些复杂地问题,例如斐波那契数列地计算机、汉诺塔、快排等。递归的能力在于用有限的语句来定义对象的无限集合。
? ? ? ? 递归结构包括两部分:
- ? 定义递归头:解答“什么时候不调用自身方法”。如果没有头,将陷入死循环,也就是递归的结束条件。
- 递归体:解答“什么时候需要调用自身方法”。??
package chap3_方法;
/**
* 使用递归求n!
*/
public class Test05 {
public static void main(String[] args) {
System.out.println(f(10)); //3628800
//计算递归耗时
long d1 = System.currentTimeMillis();
System.out.printf("%d!=%s%n",10,f(10));//3628800
long d2 = System.currentTimeMillis();
System.out.printf("递归费时:%s%n",d2-d1); //耗时32ms
}
/*求阶乘的方法*/
public static long f(int n){
if (n==0||n==1){
return 1;
}else {
return n*f(n-1);
}
}
}
递归的缺陷
? ? ? ? 简单是递归的优点之一。但是递归调用会占用大量的系统堆栈,内存耗用多,在递归调用层次多是速度要比循环慢的多,所以在使用递归方法时要慎重。
package chap3_方法;
/**
* 使用循环求n!
*/
public class Test06 {
public static void main(String[] args) {
long d3 = System.currentTimeMillis();
int n = 10;
int m = n;
int result = 1;
while (n > 1){
result *= n * (n - 1);
n -= 2;
}
long d4 = System.currentTimeMillis();
System.out.println(m+"!="+ result);
System.out.printf("普通循环费时:%s%n", d4-d3); //耗时:0
}
}
注意
- 任何能用递归解决的问题也能使用迭代解决。当递归方法可以更加自然地反映问题,并且易于理解和调试,并且不强调效率问题时,可以采用递归方法。
- 在要求高性能的情况下尽量避免使用递归,递归调用即花费时间又耗内存。
|