方法
我们在之前几个文章中从来没有提起过方法,那么方法是用来做什么的?
- 方法就是用来解决一类问题的组合。
- 方法包含于类或对象中
- 方法在程序中被创建,在其他地方被引用
方法的优点
- 使程序变得更简短而清晰。
- 有利于程序维护。
- 可以提高程序开发的效率。
- 提高了代码的重用性。
方法的命名规范
在最开始的文章中有说过什么是命名规范,方法的命名规范又是什么呢?
1.方法的名字的第一个单词应以小写字母作为开头,后面的单词则用大写字母开头写,不使用连接符。例如:addPerson。
方法的定义
- 修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。
- 返回值类型 :方法可能会返回值。returnValueType 是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType 是关键字void。
- 方法名:是方法的实际名称。方法名和参数表共同构成方法签名。
- 参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
- 方法体:方法体包含具体的语句,定义该方法的功能。
public static int age(int birthday){...}
也可以有多个参数
static float interest(float principal, int year){...}
方法的调用
Java 支持两种调用方法的方式,根据方法是否返回值来选择。
当程序调用一个方法时,程序的控制权交给了被调用的方法。当被调用方法的返回语句执行或者到达方法体闭括号时候交还控制权给程序。
当方法返回一个值的时候,方法调用通常被当做一个值。例如:
public class TestMax {
/** 主方法 */
public static void main(String[] args) {
int i = 5;
int j = 2;
//我们直接调用下面的max方法,因为返回值是int所以顶一个int的变量来进行接收
int k = max(i, j);
System.out.println( i + " 和 " + j + " 比较,最大值是:" + k);
}
/** 返回两个整数变量较大的值 */
public static int max(int num1, int num2) {
int result;
if (num1 > num2)
result = num1;
else
result = num2;
return result;
}
}
注意: 在一些其它语言中方法指过程和函数。一个返回非void类型返回值的方法称为函数;一个返回void类型返回值的方法叫做过程。
方法的重载
方法的重载(overlord),那在我们java中还有一个和重载很相似的名字叫做重写(override),那么我们这篇文章只说重载(overlord)。
为什么会有重载呢?那是因为一个事情有很多种做法,那么那么多的做法都用不同的名字来表示,很难都被记住以及使用,所以我们就把这个事情的所有做法的名字都修改成一样的,这样方便记忆和使用,只是通过参数列表的不同来区分这个方法是干嘛的。
所以总结一下:就是为了方便记忆以及使用而来的,只需要给参数列表里面的变量赋予不同的值就能实现不同的结果。
重载的含义
重载就是指一个类中的多种方法,那怎么区分方法是否被重载呢?可以通过我们的方法名和参数列表来区别:
- 方法名相同
- 参数列表不同:数据类型不同、数据类型的个数、数据类型的顺序
我们通过下面这段代码来看一下区别:
方法:
public double max(int num1, double num2) {...}
数据类型的顺序:
public double max(double num2, int num1) {...}
数据类型的类型:
public double max(char num1, int num2) {...}
数据类型的个数:
public double max(int num1, double num2, double num3) {...}
递归
什么叫做递归,它又是用来干什么的?
递归:自己直接或者间接的调用自己的方法,递归是一种描述问题和解决问题的基本方法,相比(循环)之下递归写出的代码可读性更好,不过性能上并没有优势。此外,很多算法的实现都离不开递归。
递归的基本结构:
- 递归项&递归关系 (Recursive Case) 描述大问题如何分解为小问题,也称为递归体
- 递归边界条件(Base Case) 停止递归的条件,也称为递归出口
我们来举例说明一下,我想求一个5的阶乘,怎么做,如果使用for循环怎么做,使用递归怎么做呢?
用for循环怎么做呢?代码如下:
public class Test {
public static void main(String[] args) {
System.out.println(factorial(5));
}
public static int factorial(int n) {
int sum = 1;
for (int i = n; i > 0; i--) {
sum = sum * i;
}
return sum;
}
}
运行结果如下:
递归做法:
public class Test {
public static void main(String[] args) {
System.out.println(factorial(5));
}
public static int factorial(int n) {
if (1 == n) {
return n;
} else {
return n * factorial(n - 1);
}
}
}
运行结果如下:
但是使用递归的时候需要注意的是我们在调用自身方法的时候要注意代码是否正确,否则容易引起栈内存溢出的。
递归总结
- 找到最小子问题
- 找到递归关系,即如何从顶层到达下一层的条件(关系)
- 写出最小子问题的解决过程,在恰当的时候调用自己(实现递归关系)
- 递归的分析可以将问题关系描述清楚,归的分析也是难点,是解决问题的关键
- 理解递归的执行栈可以帮助理清楚归的过程
面向对象
面向对象是一种思想,也是做事情的一种方法,说到面向对象就不得不说面向过程。
面向过程:“我该如何做”,什么都是自己做。
面向对象:“我该找谁做”,我要找哪个方法去做。
但是面向对象是依托于面向过程的。
那面向对象有什么优点呢?
- 可以将复杂的问题简单化
- 贴近于生活的解决事情的思维
- 面向对象更贴近于管理者的角度,面向过程贴近与执行者
- 面向对象有封装、继承、多态的三大特性,可以设计出低耦合的系统,让程序更加灵活,更加易于维护。
在我们刚刚开始学习JAVA的时候,我们把所有的东西都写在一个类中,这样显的代码特别的臃肿,特别多,那么现在利用面向对象的思维,我们可以把一个方法写在一个类中,在去创建另一个类,在另一个类中去调用这个方法,那如何调用呢,我们可以通过创建对象的方式,也就是new一个对象出来,通过对象.调用方法。
在一个类中我们有很多东西,那么我们今天就简单地说一下成员变量,以及方法,成员变量也就是我们的属性,当我们有一部车的时候,车子都有什么呢?车子有品牌、颜色、大小,那么这都是我们车子这个类的属性,那如何定义属性呢,由于我们没有讲权限修饰符的权限,那么我们今天统一用public修饰符来演示,请看下面代码:
public class Car{
//在这里定义我们车的属性
public String brand;
public String color;
//车子开动的方法
public void run(){
System.out.println("一辆"+color+"的"+brand+"的小汽车在奔跑...");
}
}
大家能看到我们的属性在定义的时候没有初始化,所以我们的成员变量可以再定义声明的时候不进行初始化,在使用的时候在进行给值。那么我们进行赋值和使用car这个类呢?看下面的代码,我创建了一个测试类:
public class CarTest{
public static void main(String[] args){
//创建我们车子的对象
Car car = new Car();
//我们通过car.调用属性进行赋值
car.color = "粉色";
car.brand = "GTR";
//我们通过car.调用car类中的方法
car.run();//这样我们就测试类中调用了car类中的方法
}
}
运行结果如下:
这样写我们的代码就不那么臃肿了,一个类中只是这个类的所有功能,我们复用性也高了,可读性也高了。
那么我们创建对象的方式有很多用,我带大家看一下:
public class CarTest{
public static void main(String[] args){
//创建我们车子的对象
Car car = new Car();//方式一
//这是不同的两个对象,因为我们是new出来的,和上面的car不是一辆车
Car car1 = new Car();
//匿名对象:只能当前次使用,只能用一次。
new Car();//方式二
}
}
下一篇文章继续讲解我们的面向对象的其他内容,更深入的讲一下。