第一次在csdn发帖子,小蒟蒻一枚。
今天来和大家分享一下我学到的——java的方法。
方法是类或对象最重要的组成部分。也就是一种可以实现特殊功能的代码块,方法几乎类似于传统结构化程序设计里的函数。不同的是Java的方法不可以单独使用,必须定义在类里边。一般来说一个方法实现一个功能,利于后续开发。
就拿我们常用的输出语句举个糖炒栗子 System.out.println(); 其中System就是Java系统中的一个类,out就是类下的一个对象,最后那个就是一个输出方法。
简而言之:
方法是解决一类特殊问题的组合
使代码逻辑更加清晰
实现了相同代码的复用
方法包含一个方法名和一个方法体:
修饰符:告诉编译器该如何调用这个方法,定义了该方法的访问类型。(privated ,protected ,public,缺省(就是没有—默认值))
返回值类型:如果没有返回值,则该处需要写void关键字。
参数列表:包括参数类型,个数和顺序。参数类型相当于一个占位符,当方法被调用时,值(实体参数/变量)会传递给参数(形参)。
方法体:是实现某种特殊功能的具体代码块。
格式模板:
修饰符 返回值类型 方法名(参数列表){
...
方法体
...
return 返回值;
}
举个糖炒栗子:用方法实现一个加法的功能。
public static void main(String[] args) {
int C = add(12,45);
System.out.println(C);
}
public static int add(int a,int b){
return a+b;
}
如果这个方法使用了static修饰,则这个方法属于这个类。因此使用该类的任何对象来调用这个方法时将会得到相同的执行结果。
方法调用必须有由主方法或者其他方法调用才可以运行。而且调用的参数个数,顺序和类型都必须和方法定义的想匹配。
在Java中方法的调用会根据返回值类型分为两种情况:
当方法有返回值时,方法的调用通常会被当做一个值存入一个变量当中。
int sum = add(13,24);
当方法没有返回值时,方法调用一定是以一个语句的形式出现
public static void say(){
System.out.println("Hello,World!");
}
public static void main(String[] args) {
say();
}
还有一种调用方法时通过对象:创建一个对象,用 . 运算符来访问对象当中的方法。
public static void main(String[] args) {
Object ss1 = new Object();
ss1.say();
}
public static void say(){
System.out.println("Hello,Java!!!");
}
Java允许在同一个类里,使用相同的方法名,但前提是参数列表不同。如果同一个类中包含了两个或两个以上方法的方法名相同,但形参列表不同,则被称为方法重载。
方法名必须相同。
参数列表必须不同。(参数个数,顺序和参数类型这三者一种或一种以上不同即可)
方法的返回值不同并不可以作为方法重载的标志。
当方法名相同时,编译器会自动根据调用方法的参数个数,顺序和参数类型来配对方法,如果配对失败,编译器会报错。
public static void main(String[] args) {
double c = add(1.2,5.2);
int d = add(2,5);
int e = add(5,8,41);
System.out.println(c);
System.out.println(d);
System.out.println(e);
}
public static int add(int a,int b){
return a+b;
}
public static double add(double a,double b){
return a+b;
}
public static int add(int a,int b,int c){
return a+b+c;
}
对于int add()和void add()两个方法,如果这样调用—>int a = add();,系统可以识别是调用返回值类型为int的方法;但Java调用方法时可以忽略方法返回值,如果采用如下方法来调用—>add();你还会知道你调用的时那个方法吗?可能你自己知道,但是编译器不知道!!Java系统也会糊涂的。
Java允许定义形参个数可变的参数,从而允许为方法指定数量不确定的形参。如果在声明方法的时候在参数列表中加入...这样的运算符,则表明该形参可以接受多个参数值,多个参数值被当成数组传入。也就是说可以通过下标法来调用可变参数的元素值。
public static void main(String[] args) {
getNum(1,23,3,4,76,450);
}
public static void getNum(int...a){
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]);
}
}
下面两个方法的效果完全一样。
//用可变参数来定义方法
public static void test01(int a,int ...nums);
//用数组的形式定义参数
public static void test02(int a,int [] nums);
数组形式的参数可以处于形参列表的任何一个位置,但可变参数的参数只能处于形参列表的最后,(其他所有的普通参数必须在它之前)一个方法中最多只能有一个长度可变的形参。
我们大家都常用的调用方法都是 A方法调用B方法;
而递归就是 A方法调用A方法,自己调用自己;方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制。是不是很方便!!!
我们利用递归这一思想就可以用较简单的程序来解决复杂问题,大大减少的代码量。就比如斐波那契数列这就是个经典的递归问题。
斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”。
它指的是这样一个数列:0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597......
我们不难发现规律:从第 3 项开始,每一项都等于前两项之和。
public static int fibi(int n){
if(n==0) {
return 0;
}
if(n==1||n==2){
return 1;
}
return fibi(n-1)+fibi(n-2);
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
fibi(n);
}
递归头 :表示什么时候不需要调用自身方法:递归没有头,将陷入死循环,栈会溢出。
递归体 :表示什么时候需要调用自身。
Java的参数传递方式分为两种:
按值调用:接收的是调用者提供的值。
按引用调用:接收的是调用者提供的变量地址。
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int a = in.nextInt();
int b = in.nextInt();
swap(a,b);
System.out.println("在主方法中a = "+a+" b = "+b);
}
public static void swap(int a,int b)
{
int temp = a;
a = b;
b = temp;
System.out.println("在swap方法中a = "+a+" b = "+b);
}
输入:5 6
在swap方法中a = 6 b = 5
在主方法中a = 5 b = 6
上述代码中当我们输入 5 6;我们所期望输出结果位6 5。但令人失望的是,它原封不动的输出了。这是因为,Java语言总是采用按值调用。也就是说,方法得到的是所有参数值的一个拷贝值,方法不能修改传递给它的任何参数变量的内容。
有一个很形象的例子:Java里的参数传递类似于《西游记》里的孙悟空,孙悟空拔了一根毫毛复制了一个假孙悟空,这个假孙悟空具有和孙悟空相同的能力。但不管这个假孙悟空遇到什么事,真孙悟空不会受到任何影响。哦不!会少了一根毫毛(doge.
与此类似,传入方法的是实际参数值的复制品,不管方法中对这个复制品如何操作,实际参数值本身不会受到任何影响。
我们都知道方法参数共有两种类型:
基本数据类型(数值类型等等、布尔类型)。
对象引用类型。
一个方法是并不会修改基本数据类型的值的,但是如果采用引用对象作为参数,那情况就不同了。
public static void main(String[] args) {
StringBuffer s = new StringBuffer("Hi");
System.out.println(s.toString());
change(s);
System.out.println(s.toString());
}
public static void change(StringBuffer a)
{
a.append(" Java!!!");
}
StringBuffer是一个可变序列。把它当成一个字符串去操作,只不过它与string相比是可以修改内容的。
StringBuffer的添加功能:
publicStringBuffer append(String str)
执行过程:
原本的s指向——>"Hi";
在调用change()方法的时候,使a也指向的s;
当a执行添加功能的时候,s所指向的也随之发生改变;
简单点来说:a和s都是StringBuffer的管理者,并不是StringBuffer拥有者,起初是s管理StringBuffer,在后来又引入了a来一同管理StringBuffer,所有的操作对象一直都是StringBuffer。所以我们使用a的功能的时候,会对StringBuffer产生影响。
完结撒花!