何谓方法?
System.out.prinrln(), 那么它是什么呢? 调用系统类里面的标准输出对象out里的println方法
Java方法是语句的集合, 他们在一起执行一个功能.
方法是解决一类问题的步骤的有序组合
方法包含于类或对象中
方法在程序中被创建, 在其他地方被引用
设计方法的原则: 方法的本意是功能块, 就是实现某个功能的语句块的集合. 我们设计方法的时候, 最好保持方法的原子性, 就是一个方法只完成1个功能, 这样有利于我们后期的扩展
回顾: 方法的命名规则? 驼峰命名法
实例:
public class Test {
//main方法
public static void main(String[] args) {
String add = add(6,1);//向方法内传入值6和1并将方法赋值给add
System.out.println(add);//输出add
}
//加法
public static String add(int a, int b){
/*
public访问修饰符,表示被该修饰符修饰的方法在此包的任何地方都能被调用
static静态修饰符,表示被该修饰符修饰的方法在此类被加载时一同被加载至内存中,可以直接调用
String表示该方法最后返回的值是String类型
add是方法名
()内的是形式参数a和b(int类型变量a,int类型变量b)
*/
return ("非常" + a + "+" + b);//return的空格之后跟着的就是定义的返回值
}
}
效果演示图:
输出三角形
实例:
public class Test {
//main方法
public static void main(String[] args) {
DBSJX();//这里的()就是调用操作
}
//三角形输出法
public static void DBSJX(){
/*
public访问修饰符,表示被该修饰符修饰的方法在此包的任何地方都能被调用
static静态修饰符,表示被该修饰符修饰的方法在此类被加载时一同被加载至内存中,可以直接调用
void表示该方法无返回值
DBSJX()表示方法名是DBSJX且无形式参数
*/
for (int i = 1; i <= 5; i++) {//用于输出换行,五次换行
for (int j = 5; j >= i; j--) {//占据三角形左边的空白的空格,第一层输出五个空格
System.out.print(" ");//输出空白部分空格
}
for(int j = 1; j < i * 2; j++) {//输出三角形的本体,j < i * 2是关键
// 是精髓,
System.out.print("*");//输出三角形主体
}
System.out.println();//输出换行
}
}
}
效果展示图:
方法的定义
java的方法类似于其他语言的函数, 是一段用来完成特定功能的代码片段, 一般情况下, 定义一个方法包含一下语法:
方法包含一个方法头和一个方法体. 下面是一个方法的所有部分:
修饰符: 修饰符,这是可选的, 告诉编译器如何调动该方法. 定义了该方法的访问类型.
返回值类型: 方法可能会有返回值. returnValueType是方法返回值的数据类型. 有些方法执行所需的操作, 没有返回值, 在这种情况下, returnValueType是关键字void。
方法名: 是方法的实际名称. 方法名和参数表共同构成方法签名.
**参数类型: 参数像是一个占位符. 当方法被调用时, 传递值给参数. 这个值被称为实参嚯变量. 参数列表是指方法的参数类型, 顺序和参数的个数. 参数是可选的, 方法可以不包含任何参数. **
形式参数: 在方法被调用时用于接收外界输入的数据
**实参: 调用方法时实际传给方法的数据. **
**方法体: 方法体包含具体的语句, 定义该方法的功能. **
修饰符 返回值类型 方法名(参数类型 参数名){
...
方法体
...
return 返回值;
}
实例:
public class Test {
//main方法
public static void main(String[] args) {
System.out.println(max(9,9));
}
//比较大小
public static int max(int a,int b){
int c = 0;//初始化c
if(a < b){
c = b;//a小于b则将b的值赋给c;
}else if(a > b){
c = a;//a大于b则将a的值赋给c;
}else{
c = a;
System.out.println("它们相等");//ab相等则输出相等,c的值不变
}
return c;//返回值是c
}
}
效果演示图:
方法调用
调用方法: 对象名.方法名(实参列表)
Java支持两种调用方法的表示, 根据方法是否返回值来选择.
当方法返回一个值的时候, 方法调用通常被当做一个值. 例如:
int larger = max(30, 40);
如果方法返回值是void, 方法调用一定是一条语句.
System.out.println("Hello,hehehe!");
课后拓展了解: 值传递 和 引用传递
值传递是指传递两个变量之间的值, 当改变其中一个变量的值的时候, 另一个值不会改变, 他们是两个不同的地址储存着相同的值;
引用传递是指传递对象的储存地址, 他们实际上是在同一个地址中取同一个值
方法的重载
重载就是在一个类中, 有相同的函数名称, 但形参不同的函数
方法的重载规则
方法名称必须相同
参数列表必须不同(个数不同, 或类型不同, 或参数列表顺序不同等)
方法的返回类型可以相同也可以不相同
仅仅返回类型不同不足以成为方法的重载
实现理论:
方法名称相同时, 编译器会根据调通方法的参数个数, 参数类型等去逐个匹配, 以选择对应的方法, 如果匹配失败, 编译器会报错.
实例:
public class Test {
//main方法
public static void main(String[] args) {
System.out.println(max(0,0));
}
//比较大小
public static int max(int a,int b){//数据类型全是int
int c = 0;
if(a < b){
c = b;
}else if(a > b){
c = a;
}else{
System.out.println("它们相等");
}
return c;
}
public static double max(double a,double b){//方法的数据类型全是double
double c = 0;
if(a < b){
c = b;
}else if(a > b){
c = a;
}else{
System.out.println("它们相等");
}
return c;
}
}
效果演示图:
比大小
实例:
public class Test {
//main方法
public static void main(String[] args) {
System.out.println(XJ(2,5,5,4));
}
//比较大小
public static int XJ(int a,int b){//数据类型全是int
int c = 0;
c = a+b;
return c;
}
public static double XJ(int a,int b,int c,int d){//返回值类型int,接收返回值的类型是double,值会被转为double类型
int z = 0;
z = a+b+c+d;
return z;
}
}
效果演示图:
命令行传参
有时候你希望运行一个程序的时候再传递给他消息. 这要靠传递命令行参数给main()函数实现
public class Test {
public static void main(String args[]){
/*
public访问修饰符,表示被该修饰符修饰的方法在此包的任何地方都能被调用
static静态修饰符,表示被该修饰符修饰的方法在此类被加载时一同被加载至内存中,可以直接调用
void表示该方法无返回值
main表示方法名是main
(String args[])表示参数类型是String 变量是名称为args的空数组,[]表示数组
*/
for(int i = 0;i < args.length;i++){//args.length返回的是args的数组长度,数组有多长这个循环就执行多少次
System.out.println("args[" + i + "]: " + args[i]);//输出args[i] : args中第i个位置的值
}
}
}
现在到Test文件的所在位置的文件夹
按住Shift单机右键,选择"在此处打开Powershell窗口"
输入javac Test.java 编译class文件
返回到Test文件的上级src目录(输入cd …按下回车返回上级)
输入java 包名(我的包名是com.kss.demo).文件名(Test) this a dog
就会返回一串文字
args[0]: this
args[1]: a
args[2]: dog
可变参数(不定向参数)
JDK1.5开始, Java支持传递同类型的可变参数给一个方法
在方法声明中, 在指定参数类型后加一个省略号(…)
一个方法中只能指定一个可变参数, 它必须是方法的最后一个参数. 任何普通的参数必须在它之前声明
输出最大值
使用案例:
//输出最大值
public class Test {
//main方法
public static void main(String args[]){
printMax(16445,251653,56516,84561,6844,8452,1238,64156,86678);
}
public static void printMax(double...numbers){//方法目的是打印最大的值,但不确定要传入多少个参数
if(numbers.length == 0){//判断传递的参数长度是否为0
System.out.println("未传入参数");//输出错误提示
return;//return之后的代码不再执行
}
double result = numbers[0];//给储存值的变量初始化
//总是输出最大的值
for(int i = 1;i < numbers.length;i++){//数组有多长就循环多少次
if(numbers[i] > result){//从数组的第一个位的值开始和第二位得值比较
result = numbers[i];//始终把较大的值赋值给result
}
}
System.out.println("最大的值为: " + result);//输出结果
}
效果演示图:
冒泡排序
实例:
//冒泡排序
public class Test {
//main方法
public static void main(String args[]){
Scanner s = new Scanner(System.in);//实例化Scanner对象
int[] A = new int [10];//创建数组A初始长度为10
for(int i = 0;i < A.length;i++){//循环次数为A的长度
A[i] = s.nextInt();//将用户的每次输入都存入当前循环的索引中
}
System.out.println(add(A));//输出 使用add方法处理后的A
}
public static String add(int...a){//创建 公共 静态方法 接收的返回值的类型为String 方法名为add 形式参数类型为int 传的值数量不限定 形参为a
if(a.length == 0){//如果a的长度为零
System.out.println("未传递参数");//输出提示语
return "";//返回一个空串
}
//冒泡排序
int b = 0;//创建变量b储存临时数值
for (int i = 0; i < a.length; i++) {//循环次数为a的长度-1
for (int j = i+1; j < a.length; j++) {//循环次数为a的长度-1
if(a[i] > a[j]){//如果前一个值小于后一个值
b = a[i];//将第一个值赋值给储存临时数值的变量b
a[i] = a[j];//将前后两个值进行替换(后值覆盖前值)
a[j] = b;//将之前储存的第一个值赋给第二个索引g
}
}
}
String z = Arrays.toString(a);//创建字符串变量接收被数组方法(Arrays)的字符串转化方法(toString)转化的数组a
return z;//返回字符串z
}
}
效果演示图:
递归讲解
A方法调用B方法,我们很容易理解!
递归就是: A方法调用A方法! 就是自己调用自己
利用递归可以用简单的程序来解决一些复杂的问题. 它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解, 递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大的减少了程序的代码量. 递归的能力在于用有限的语句来定义对象的无限集合.
**递归结构包括两个部分: **
**递归头: 什么时候不调用自身方法, 如果没有头, 将陷入死循环. **
**递归体: 什么时候需要调用自身方法. **
**实例: **
public class Test {
//main方法
public static void main(String args[]) {
System.out.println(Recursive(40));//输出Recursive(40)返回的值
}
//斐波拉契数递归实现法 数字40以上不建议使用递归
public static int Recursive(int a){//定义公共的静态方法 接收的类型为int 方法名为Recuesive 方法形参为int类型 a
if(a == 1 | a == 2){//a等于1或2时直接返回1;
return 1;
}
if(a > 2){//a大于2时调用自身重复处理数据直到将a处理到为2为止返回期间调用自身处理的所有数据
return Recursive(a - 1) + Recursive(a - 2);//调用自身处理 a - 1 与 a - 2 并返回他们的和,当 a - 2 不等于2时,继续调用自身处理a - 1 与 a - 2,且返回他们的和,直到 a - 2 等于2为止
}
return -1;
}
}
效果演示图:
java内存机制是栈机制, 每调用一个方法就往上堆积一层, 从上往下一层一层执行并返回结果给下一层, 直到main方法执行完毕进程结束, 可以看到超过45层以后每加一层运算时间都是翻倍的,当层数过多时会严重占用计算机资源(我自己玩的时候把上面实参写到100,内存打穿了进程直接死掉了), 所以递归方法虽然代码简洁, 但是不适合参数较大的数值处理, 比较适合小规模的数据处理
制作简易计算器
-
写四个方法: 加减乘除
-
利用循环 + switch进行用户交互
-
传递需要操作的两个数
-
输出结果
实例:
public class Test {
//main方法
public static void main(String args[]) {
System.out.println("请输入数字与运算符进行运算: ");//输出提示语
Scanner s = new Scanner(System.in);//Scanner对象实例化
while(true){//死循环while,计算永不停息
double a = s.nextDouble();//定义double类型变量a接收输入的第1个数字
String c = s.next();//定义String类型变量c接收用户输入的运算符
double b = s.nextDouble();//定义double类型变量b接收输入的第2个数字
if (c.equals("+")){//使用equals方法判定用户输入的运算符是否是+号
System.out.println(a + "+" + b + "=" + jia(a,b));//输出8
}else if(c.equals("-")){//使用equals方法判定用户输入的运算符是否是-号
System.out.println(a + "-" + b + "=" + jian(a,b));//输出最终计算结果
}else if(c.equals("*")){//使用equals方法判定用户输入的运算符是否是*号
System.out.println(a + "*" + b + "=" + cheng(a,b));//输出最终计算结果
}else if(c.equals("/")){//使用equals方法判定用户输入的运算符是否是/号
System.out.println(a + "-" + b + "=" + chu(a,b));//输出最终计算结果
}
}
}
public static double jia(double a,double b){//定义加法方法 设定两个形参a和b
return a+b;//返回a+b的和
}
public static double jian(double a,double b){//定义减法方法 设定两个形参a和b
return a-b;//返回a-b的差
}
public static double cheng(double a,double b){//定义乘法方法 设定两个形参a和b
return a*b;//返回a*b的积
}
public static double chu(double a,double b){//定义除法方法 设定两个形参a和b
return a/b;//返回a/b的商
}
}
效果演示图: