在面向对象编程中,方法(Method)是类或对象中用于执行特定任务的一段代码。方法可以访问和操作对象的属性,并提供了一种封装行为的方式。
方法通常用于描述对象的行为或操作,它们定义了对象可以执行的操作,并在需要时接受输入参数并返回结果。方法可以被其他代码调用,并且可以在需要时被重复使用,从而实现了代码的模块化和重用。
方法一般由以下几个组成部分:
package com.determination;
public class Day11601 {
//main方法
public static void main(String[] args) {
sayHello();
System.out.println("两个数中最大的是:"+max(4,5));
}
/*
修饰符 返回值类型 方法名(。。。){
方法体
返回值
}
*/
public static void sayHello()
{
System.out.println("Hello world!");
return;
}
public static int max(int a,int b)
{
return a>b?a:b;
}
}
当我们调用一个方法时,程序会跳转到该方法的代码块中执行相应的操作。在方法内部,我们可以通过参数来访问传递进来的数据,并通过方法体中的代码来处理这些数据。最后,方法可以根据需要返回一个结果给调用方。
在面向对象编程中,静态方法(Static Method)是一种特殊的方法,不需要创建对象实例即可调用。静态方法是直接与类相关联的,而不是与类的对象相关联的。
使用static关键字来定义静态方法。在静态方法内部,不能直接访问非静态成员变量或方法,因为非静态成员变量和方法需要依赖于对象的实例才能被访问。但是,静态方法可以访问静态成员变量或静态方法。
静态方法在设计模式中有广泛应用,例如工厂模式。在工厂模式中,我们使用静态方法来创建对象,而不是通过new操作符来创建对象。这种方式可以将对象的创建逻辑封装在方法中,并提供更加灵活的对象创建方式。
静态方法还可以用于工具类或辅助类中,这些类通常只提供一些公用方法,而不需要维护任何状态或对象实例。使用静态方法可以避免创建多余的对象实例,从而提高程序的性能和效率。
Day11602.java
package com.determination;
public class Day11602 {
public static void main(String[] args) {
Student.say();
}
}
Student.java
package com.determination;
public class Student {
//静态方法·
public static void say()
{
System.out.println("学生说话了!!");
}
}
输出
学生说话了!!
在面向对象编程中,非静态方法(Non-static Method)是与类的对象相关联的方法。也就是说,只有当类的一个实例化对象被创建后,才能调用非静态方法。
非静态方法是通过对象来调用的,因此它们可以直接访问和操作对象的非静态成员变量或方法。在非静态方法内部,可以使用this关键字来引用当前对象,从而获取或修改对象的状态。
使用非静态方法可以实现面向对象编程中的封装和抽象特性。非静态方法通常用于描述对象的行为或操作,例如读取或修改对象的状态、执行某些动作、计算属性等等。
当我们调用一个非静态方法时,程序首先需要创建一个对象实例,然后通过该对象来调用方法。由于每个对象都有一份独立的状态,因此同一个类的不同对象可能会产生不同的结果。
11602.java
package com.determination;
public class Day11602 {
public static void main(String[] args) {
//Student.say();
Student student=new Student();
student.say();
}
}
Student.java
package com.determination;
public class Student {
//静态方法·
// public static void say()
// {
// System.out.println("学生说话了!!");
// }
//非静态方法
public void say()
{
System.out.println("学生说话了!");
}
}
static 关键字修饰的成员(包括静态方法和静态变量)是与类一起加载的。
在 Java 中,当类被加载到内存中时,静态成员会随着类的加载而加载,并且在类加载过程中只会加载一次。静态成员的加载顺序是按照定义的顺序进行的。
当类被加载时,Java 虚拟机会为该类分配内存,并且静态成员会被初始化。静态变量会被赋予默认值(如果有的话),或者通过显式赋值来初始化。静态方法也会被加载到内存中,供类直接调用。
由于静态成员是和类相关联的,它们可以在没有创建对象实例的情况下被访问和使用。我们可以通过类名直接调用静态方法或访问静态变量,无需创建对象。
需要注意的是,静态成员在内存中存在于整个程序执行期间,直到程序结束或类被卸载。因此,静态成员应谨慎使用,避免滥用静态变量,特别是在多线程环境下,需要考虑线程安全性。
需要注意的是:
实参与形参的参数类型要对应,不能出现定义的形参是int型,结果传递过来的是字符型char
public void swap(int x, int y) {
int temp = x;
x = y;
y = temp; //没有返回值,仅仅是对a,b的副本x,y进行了交换数值
}
int a = 1, b = 2;
swap(a, b);
System.out.println("a=" + a + ", b=" + b); // 输出 a=1, b=2
在上面的例子中,swap 方法接收两个 int 类型的参数 x 和 y,通过将 x 和 y 的值进行交换来实现交换两个变量的值。但是,当我们调用 swap 方法时,并没有改变 a 和 b 的值,因为 swap 方法接收的是 a 和 b 的副本,交换操作只是在副本中进行的。
public void changeName(Student s, String name) {
s.setName(name);
}
Student stu = new Student("Tom", 18);
changeName(stu, "Jerry");
System.out.println(stu.getName()); // 输出 Jerry
changeName 方法接收一个 Student 类型的对象 s 和一个 String 类型的参数 name,通过修改 s 对象的姓名来实现修改学生的姓名。当我们调用 changeName 方法时,传递的是 stu 对象的引用,因此在方法内部对 s 对象的修改会影响到 stu 对象本身。
方法的重载(Method Overloading)是指在一个类中可以定义多个方法,它们具有相同的名称但参数列表不同(参数个数、参数类型或参数顺序)。通过方法的重载,可以方便地使用相同的方法名进行不同的操作。
方法的重载有以下特点:
例如,下面是一个计算两个整数之和的方法的重载示例:
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public double add(double a, double b) {
return a + b;
}
}
Calculator 类定义了两个名为 add 的方法,一个接收两个 int 类型的参数,另一个接收两个 double 类型的参数。这样,当我们调用 add 方法时,可以根据传入的参数类型自动选择匹配的方法进行计算。
使用方法重载的好处包括:
在 Java 中,命令行参数以字符串数组的形式传递给 main 方法。main 方法的声明如下:
public static void main(String[] args)
其中,args 是一个字符串数组,包含了传递给程序的所有命令行参数。args 数组的长度即为传递参数的个数。
package com.determination;
public class Day11603 {
public static void main(String[] args) {
//args.length 数组长度
for(int i=0;i<args.length;i++)
{
System.out.println("args["+i+"]:"+args[i]);
}
}
}
然后如下图所示操作
显示结果:
需要注意的是,命令行参数总是以字符串的形式传递给程序。如果需要将其转换为其他类型,需要进行相应的类型转换操作。
可变参数(Varargs)是 Java 5 中引入的一个特性,它允许我们在方法中接受不定数量的参数。可变参数使得方法在调用时更加灵活,可以传递任意数量的参数。
在 Java 中,可变参数通过使用省略号 (…) 来声明。可变参数必须是方法的最后一个参数,且只能有一个可变参数。
下面是一个使用可变参数的示例:
public class VarargsExample {
public static void main(String[] args) {
printNumbers(1, 2, 3);
printNumbers(4, 5, 6, 7, 8);
printNumbers(9);
}
public static void printNumbers(int... numbers) {
System.out.println("Numbers:");
for (int number : numbers) {
System.out.println(number);
}
}
}
在上述示例中,printNumbers 方法使用了可变参数 numbers。我们可以向该方法传递任意数量的整数参数。在方法内部,我们可以像操作普通数组一样来处理可变参数。在printNumbers 方法中,我们遍历可变参数数组,并打印每个数字。
Numbers:
1
2
3
Numbers:
4
5
6
7
8
Numbers:
9
需要注意以下几点:
递归(Recursion)是一种常见的算法设计技巧,它是通过函数自身调用来解决问题的方法。在递归过程中,函数会不断调用自身,直到达到某个终止条件为止。递归通常可以让代码更加简洁而优雅,但同时也需要注意可能带来的性能问题和栈溢出等问题。
public class RecursionExample {
public static void main(String[] args) {
int result = factorial(5);
System.out.println("Factorial of 5 is " + result);
}
public static int factorial(int n) {
if (n == 0) {
return 1;
} else {
return n * factorial(n - 1);
}
}
}
上述代码使用递归的方式计算阶乘。在 factorial 方法内部,我们首先判断传入的参数是否为 0,如果是,则返回 1。否则,我们将 n 乘以 (n-1) 的阶乘结果,实现递归调用。
Factorial of 5 is 120
递归虽然在某些情况下可以使代码更加简洁而优雅,但有时也可能会带来一些问题。递归调用需要占用栈空间,如果递归层数过多,可能会导致栈溢出。另外,递归的效率可能不如迭代法,因为在递归调用过程中需要不断地压栈和出栈,增加了额外的开销。
递归详细讲解
写一个计算器要求实现加减乘除功能,并且能够循环接收新的数据
package com.determination;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class Day11604 {
public static void main(String[] args) {
System.out.println("请输入数字,输入'exit'结束:");
Scanner scanner=new Scanner(System.in);
// 创建一个动态大小的数组列表
List<Integer> numbers = new ArrayList<>();
while (scanner.hasNext()) {
String input = scanner.next();
// 判断是否输入 'exit',如果是则退出循环
if (input.equals("exit")) {
break;
}
try {
// 将用户输入的字符串解析为整数,并添加到数组列表中
int number = Integer.parseInt(input);
numbers.add(number);
} catch (NumberFormatException e) {
System.out.println("无效的输入,请重新输入数字或 'exit' 来结束。");
}
}
// 将数组列表转换为数组
double[] array = new double[numbers.size()];
for (int i = 0; i < numbers.size(); i++) {
array[i] = numbers.get(i);
}
System.out.println("相加的结果为:"+add(array));
System.out.println("相减的结果为:"+decrease(array));
System.out.println("相乘的结果为:"+multiple(array));
System.out.println("相除的结果为:"+divde(array));
}
public static double add(double ... number)
{
double sum=0;
for(int i=0;i<number.length;i++)
{
sum+=number[i];
}
return sum;
}
public static double decrease(double ... number)
{
double res=number[0];
// System.out.println(res);
for(int i=1;i<number.length;i++)
{
res-=number[i];
}
return res;
}
public static double multiple(double ... number)
{
double res=number[0];
for(int i=1;i<number.length;i++)
{
res*=number[i];
}
return res;
}
public static double divde(double ... number)
{
double res=number[0];
for(int i=1;i<number.length;i++)
{
res/=number[i];
}
return res;
}
}
运行:
请输入数字,输入'exit'结束:
10 5 exit
相加的结果为:15.0
相减的结果为:5.0
相乘的结果为:50.0
相除的结果为:2.0