06-方法

06-方法

  • 6.1 引言
    • 方法可以用于定义可重用的代码以及组织和简化编码。
  • 6.2 定义方法
    • 方法的定义由方法名称、参数、返回值类型以及方法体组成。
    • 定义方法的语法如下所示:
      修饰符   返回值类型    方法名(参数列表){
      //方法体;
      }
      
    • 方法头是指方法的修饰符、返回值类型、方法名和方法的参数。
    • 方法可以返回一个值。有些方法只是完成某些要求的操作,而不返回值。在System.exit、System.out.println方法中返回值类型也是void。如果方法有返回值,则称为带返回值的方法,否则就称这个方法为void方法。
    • 定义在方法头中的变量称为形式参数或者简称为形参。参数就像是占位符。当调用方法时,就给参数传递一个值,这个值称为实际参数或者实参。参数列表指明方法中参数的类型、顺序和个数。方法名和参数列表一起构成方法签名。参数是可选的,也就是方法可以不包含参数。
    • 为使带返回值的方法能返回一个结果,必须要使用带关键字return的返回语句。执行return语句时方法终止。
    • 在其他语言中,方法称为过程或函数。这些语言中,带返回值的方法称为函数,返回值类型是void的方法称为过程。
    • 在方法头中,需要对每一个参数进行单独的数据类型声明。
    • 定义是指被定义的项是什么,而声明通常是指被声明的项分配内存来存储数据。
  • 6.3 调用方法
    • 为了之用方法,必须使用它。根据方法是否有返回值,调用方法有两种途径。
    • 如果方法返回一个值,对方法的调用通常就当做一个值处理。
    • 如果方法返回void,对方法的调用必须是一条语句。
    • 在Java中,带返回值的方法也可以当做语句调用。这种情况下,函数调用者只需要忽略返回值即可。虽然很少这么做,但是如果调用者对返回值不感兴趣,这样也是允许的。
    • 当调用一个方法时,程序控制就转移到被调用的方法。当执行完return语句或执行到表示方法结束的右括号时,被调用的方法将程序控制返还给调用者。
      package chapter06;
      
      public class TestMax {
          public static void main(String[] args){
              int i = 5;
              int j = 2;
              int k = max(i,j);
              System.out.println("The maximum of " + i + " and " + j + " is " + k);
          }
          public static int max(int num1,int num2) {
              int result;
              if (num1 > num2)
                  result = num1;
              else
                  result = num2;
              return result;
          }
      }
      
      
    • 方法能够带来代码的共享和重用。除了可以在TestMax中调用max方法,还可以在其他类中调用他。如果创建了一个新类,可以通过使用“类名.方法名”来调用max方法。
    • 每当调用一个方法时,系统会创建一个活动记录(也称活动框架),用于保存方法中的参数和变量。活动记录置于一个内存区域中,称为调用栈。调用栈也称为执行栈、运行时栈,或者一个机器栈,常简称为栈。当一个方法调用另一个方法时,调用者的活动记录保持不变,一个新的活动记录被创建用于被调用的新方法。一个方法结束运行返回到调用者,其相应的活动记录也被释放。
    • 调用栈以后进先出的方式来保存活动记录。
  • 6.4 void方法与返回值方法
```java
package chapter06;

public class TestVoidMethod {
    public static void main(String[] args){
        System.out.print("The grade is ");
        printGrade(78.5);
        System.out.print("The grade is ");
        printGrade(59.5);
    }
    public static void printGrade(double score){
        if (score >= 90.0){
            System.out.println('A');
        }
        else if (score >= 80.0){
            System.out.println('B');
        }
        else if (score >= 70.0){
            System.out.println('C');
        }
        else if (score >= 60.0){
            System.out.println('D');
        }
        else {
            System.out.println('F');
        }
    }
}

```
```java
package chapter06;

public class TestReturnGradeMethod {
    public static void main(String[] args){
        System.out.print("The grade is " + getGrade(78.5));
        System.out.print("\nThe grade is " + getGrade(59.5));
    }
    public static char getGrade(double score){
        if (score >= 90.0)
            return 'A';
        else if (score >= 80.0)
            return 'B';
        else if (score >= 70.0)
            return 'C';
        else if (score >= 60.0)
            return 'D';
        else 
            return 'F';
    }
}

```
- return语句对于void方法不是必须的,但他能用于方法并返回到方法的调用者。他的语法是:
    ```java
    return;
    ```
- 这种用法很少,对视对于改变void方法中的正常流程控制是很有用的。
  • 6.5 按值传参

    • 调用方法的时候是通过传值的方式将实参传递给形参的。
    • 方法的最强大之处在于他处理参数的能力。调用方法时,需要提供参数,他们必须与方法签名中所对应的形参次序相同。这称为参数顺序匹配。
    • 实参必须与方法签名中定义的形参在次序和数量上匹配,在类型上兼容。类型兼容是指不需要经过显式的类型转换,实参的值就可以传递给形参。
    • 当调用参数的方法时,实参的值传递给形参,这个过程称为按值传递。如果实参是变量而不是字面值,则将该变量的值传递给形参。无论形参在方法中是否改变,该变量都不受影响。
      package chapter06;
      
      public class Increment {
          public static void main(String[] args){
              int x = 1;
              System.out.println("Before the call,x is " + x);
              increment(x);
              System.out.println("After the call,x is " + x);
          }
          public static void increment(int n){
              n++;
              System.out.println("n inside the method is " + n);
          }
      }
      
      
      package chapter06;
      
      public class TestPassByValue {
          public static void main(String[] args){
              int num1 = 1;
              int num2 = 2;
              System.out.println("Before invoking the swap method,num1 is " + num1 + "and num2 is " + num2);
              swap(num1,num2);
              System.out.println("After invoking the swap method,num1 is " + num1 + "and num2 is " + num2);
          }
          public static void swap(int n1,int n2){
              System.out.println("\tInside the swap method");
              System.out.println("\t\tBefore swapping, n1 is " + n1 + "and n2 is " + n2);
              int temp = n1;
              n1 = n2;
              n2 = temp;
              System.out.println("\t\tAfter swapping, n1 is " + n1 + "and n2 is " + n2);
          }
      }
      
      
  • 6.6 模块化代码

    • 模块化的代码是的代码易于维护和调试,并且是的代码可以被调用。
      package chapter06;
      
      import java.util.Scanner;
      
      public class GreatestCommonDivisorMethod {
          public static void main(String[] args){
              Scanner input = new Scanner(System.in);
              System.out.print("Enter first integer: ");
              int n1 = input.nextInt();
              System.out.print("Enter second integer: ");
              int n2 = input.nextInt();
              System.out.println("The greatest common divisor for " + n1 + " and " + n2 + " is " + gcd(n1,n2));
          }
          public static int gcd(int n1,int n2){
              int gcd = 1;
              int k = 2;
              while (k <= n1 && k <= n2){
                  if (n1 % k == 0 && n2 % k == 0)
                      gcd = k;
                  k++;
              }
              return gcd;
          }
      }
      
      
    • 通过将求最大公约数的代码封装在一个方法中,这个程序就具备以下几个优点:
      • 1、他将计算最大公约数的问题和main方法中的其他代码分隔开,这样做会使得逻辑更加清晰而且程序的可读性更强。
      • 2、将计算最大公约数的错误限定在gcd方法中,这样就缩小了调试的范围。
      • 3、现在,其他程序可以重复使用gcd方法。
    package chapter06;
    
    public class PrimeNumberMethod {
        public static void main(String[]  args){
            System.out.println("The first 50 prime numbers are \n");
            printPrimeNumbers(50);
        }
        public static void printPrimeNumbers(int numberOfPrime){
            final int NUMBER_OF_PRIME_PER_LINE = 10;
            int count = 0;
            int number = 2;
            while (count < numberOfPrime){
                if (isPrime(number)){
                    count++;
                    if (count % NUMBER_OF_PRIME_PER_LINE == 0){
                        System.out.printf("%-5d\n",number);
                    }
                    else 
                        System.out.printf("%-5d",number);
                }
                number++;
            }
        }
        public static boolean isPrime(int number){
            for (int divisor = 2;divisor <= number / 2;divisor++){
                if (number % divisor == 0){
                    return false;
                }
            }
            return true;
        }
    }
    
    
  • 6.7 示例学习:将十六进制数转换为十进制数

    package chapter06;
    
    import java.util.Scanner;
    
    public class Hex2Dec {
        public static void main(String[] args){
            Scanner input = new Scanner(System.in);
            System.out.print("Enter a hex number: ");
            String hex = input.nextLine();
            System.out.println("The decimal value for hex number " + hex + " is " + hexToDecimal(hex.toUpperCase()));
        }
        public static int hexToDecimal(String hex){
            int decimalValue = 0;
            for (int i = 0;i < hex.length();i++){
                char hexChar = hex.charAt(i);
                decimalValue = decimalValue * 16 + hexCharToDecimal(hexChar);
            }
            return decimalValue;
        }
        public static int hexCharToDecimal(char ch){
            if (ch >= 'A' && ch <= 'F')
                return 10 + ch - 'A';
            else 
                return ch - '0';
        }
    }
    
    
  • 6.8 重载方法

    • 重载方法使得你可以使用同样的名字来定义不同方法,只要他们的参数列表是不同的。
      package chapter06;
      
      public class TestMethodOverloading {
          public static void main(String[] args){
              System.out.println("The maximum of 3 and 4 is " + max(3,4));
              System.out.println("The maximum of 3.0 and 5.4 is " + max(3.0,5.4));
              System.out.println("The maximum of 3.0, 5.4 and 10.14 is " + max(3.0,5.4,10.14));
          }
          public static int max(int num1,int num2){
              if (num1 > num2)
                  return num1;
              else 
                  return num2;
          }
          public static double max(double num1,double num2){
              if (num1 > num2)
                  return num1;
              else 
                  return num2;
          }
          public static double max(double num1,double num2,double num3){
              return max(max(num1,num2),num3);
          }
      }
      
      
    • 重载方法可以使得程序更加清晰,以及更加具有可读性。执行同样功能但是具有不同参数类型的方法应该使用同样的方法。
    • 被重载的方法必须具有不同的参数列表。不能基于不同修饰符或返回值类型来重载方法。
    • 有时调用一个方法时,会有两个或更多可能的匹配,但是,编译器无法判断哪个是最精确的匹配。这称为歧义调用。歧义调用会产生一个编译错误。
  • 6.9 变量的作用域

    • 在方法中定义的变量称为局部变量。局部变量的作用域是从变量声明的地方开始,知道包含该变量的块结束为止。局部变量都必须在使用之前进行声明和赋值。
    • 可以在一个方法中的不同块里声明同名的局部变量,但是,不能再嵌套块中或同意块中两次声明同一个变量。
    • 一种常见的错误是在for循环中国声明一个变量,然后试图在循环外使用它。
  • 6.10 示例学习:生成随机字符

    package chapter06;
    
    public class TestRandomCharacter {
        public static void main(String[] args){
            final int NUMBER_OF_CHARS = 175;
            final int CHARS_PER_LINE = 25;
            for (int i = 0;i < NUMBER_OF_CHARS;i++){
                char ch = RandomCharacter.getRandomLowerCaseLetter();
                if ((i + 1) % CHARS_PER_LINE == 0)
                    System.out.println(ch);
                else
                    System.out.print(ch);
            }
        }
    }
    
    
    package chapter06;
    
    public class RandomCharacter {
        public static char getRandomCharacter(char ch1,char ch2){
            return (char)(ch1 + Math.random() * (ch2 - ch1 + 1));
        }
        public static char getRandomLowerCaseLetter(){
            return getRandomCharacter('a','z');
        }
        public static char getRandomUpperCaseLetter(){
            return getRandomCharacter('A','Z');
        }
        public static char getRandomDigitCharacter(){
            return getRandomCharacter('0','9');
        }
        public static char getRandomCharacter(){
            return getRandomCharacter('\u0000','\uFFFF');
        }
    }
    
    
  • 6.11 方法抽象和逐步求精

    方法抽象是通过将方法的使用和他的实现分离来实现的。
    当编写一个程序时,可以使用“分治”策略,也称为逐步求精,将大问题分解成小问题,子问题又分解成更小、更容易处理的问题。

    • 6.11.1 自顶向下的设计
    • 6.11.2 自定向下和自顶向上的实现
    • 6.11.3 实现细节
    • 6.11.4 逐步求精的优势
      • 1、更简单的程序
      • 2、重用方法
      • 3、易于开发、调试和测试
      • 4、更方便团队合作
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,841评论 5 472
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,415评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,904评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,051评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,055评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,255评论 1 278
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,729评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,377评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,517评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,420评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,467评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,144评论 3 317
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,735评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,812评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,029评论 1 256
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,528评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,126评论 2 341