CodeGym /Java 博客 /随机的 /方法声明
John Squirrels
第 41 级
San Francisco

方法声明

已在 随机的 群组中发布
你好!您已经知道如何使用字段和方法创建您自己的类。现在我们将详述方法。
方法声明 - 1
当然,我们已经在课程中不止一次这样做过,但我们主要介绍了一般性知识。今天,我们将剖析方法,研究它们的构成、创建它们的各种方法以及如何管理它们。:) 我们走吧!

方法声明

所有定义方法的代码都称为方法声明。方法声明的一般形式可以描述如下:

access modifier, return type, method name (parameter list) {
    // method body
}
作为例子,看一下类的各种方法的声明Dog

public class Dog {

   String name;

   public Dog(String name) {
       this.name = name;
   }

   public static void main(String[] args) {
       Dog max = new Dog("Max");
       max.woof();

   }

   public void woof() {
       System.out.println("A dog named " + name + " says \"Woof, woof!\"");
   }

   public void run(int distanceInFeet) {
       System.out.println("A dog named " + name + " ran " + distanceInFeet + " feet!");
   }

   public String getName() {
       return name;
   }
}

1.访问修饰符

访问修饰符总是首先指示。 该类的所有Dog方法都标有public修饰符。这意味着我们可以从任何其他类中调用它们:

public class Main {

   public static void main(String[] args) {

       Dog butch = new Dog("Butch");
       butch.run(100);
   }

}
如您所见,Dog类的方法很容易在Main类中访问。由于public修饰符,这是可能的。在 Java 中,还有其他修饰符。它们并不都允许在其他类中使用方法。我们将在其他课程中讨论它们。要记住的主要事情是修饰符负责什么:一个方法是否可以在其他类中访问:)

2.静态关键字

其中一种Dog方法 ,用关键字staticmain()标记。它也是方法声明的一部分,我们已经知道它的含义了。我们在课程开始给出的方法声明模板中没有提到它,因为它是可选的。如果指定,则它必须位于访问修饰符之后。还记得在最近的课程中我们谈到了静态(类)变量吗?当应用于方法时,this 关键字具有大致相同的含义。如果方法是静态的,则可以在不引用类的特定对象的情况下使用它。事实上,你不需要一个对象来运行静态方法Dogmain()Dog班级。没有一个它会运行得很好。如果这个方法不是静态的,那么我们首先需要创建一个对象才能运行它。

3.返回值

如果我们的方法应该返回一些东西,那么我们指定返回值的类型。从 getter 的示例中可以明显看出这一点getName()

public String getName() {
   return name;
}
它返回一个String对象。如果方法不返回任何内容,则使用关键字voidwoof()代替,如方法中所示:

public void woof() {
   System.out.println("A dog named " + name + " says \"Woof, woof!\"");
}

同名方法

在某些情况下,我们需要几种不同的方式来调用一个方法。为什么不创造我们自己的人工智能?亚马逊有 Alexa,苹果有 Siri,那么我们为什么不应该有一个呢?:) 在电影钢铁侠中,托尼·斯塔克创造了他自己不可思议的人工智能贾维斯。让我们向这位了不起的人物致敬,并以他的名字命名我们的 AI。:) 我们需要做的第一件事是教 Jarvis 向进入房间的人打招呼(如果这样一个惊人的智慧竟然是不礼貌的,那就太奇怪了)。

public class Jarvis {

   public void sayHi(String name) {
       System.out.println("Good evening, " + name + ". How are you?");
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark");
   }
}
控制台输出: 晚上好,托尼·斯塔克。你好吗? 非常好!贾维斯现在可以欢迎客人了。当然,更多的时候是他的主人托尼·斯塔克。可万一他一个人不来呢!但是我们的sayHi()方法只接受一个参数。所以它只能迎接一个进入房间的人,而忽略另一个人。不太礼貌,同意吗?:/ 在这种情况下,我们可以通过简单地编写 2 个同名但不同参数的方法来解决问题:

public class Jarvis {

   public void sayHi(String firstGuest) {
       System.out.println("Good evening, " + firstGuest + ". How are you?");
   }

   public void sayHi(String firstGuest, String secondGuest) {
       System.out.println("Good evening, " + firstGuest + " and " + secondGuest + ". How are you?");
   }

}
这称为方法重载。方法重载让我们的程序更加灵活并适应各种工作方式。让我们回顾一下它是如何工作的:

public class Jarvis {

   public void sayHi(String firstGuest) {
       System.out.println("Good evening, " + firstGuest + ". How are you?");
   }

   public void sayHi(String firstGuest, String secondGuest) {
       System.out.println("Good evening, " + firstGuest + " and " + secondGuest + ". How are you?");
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark");
       jarvis.sayHi("Tony Stark", "Captain America");
   }
}
控制台输出: 晚上好,托尼·斯塔克。你好吗?晚上好,托尼·斯塔克和美国队长。你好吗? 太好了,两个版本都有效。:) 但是我们没有解决问题!如果有三个客人怎么办?当然,我们可以sayHi()再次重载该方法,以便它接受三个来宾姓名。但可能有 4 或 5 个。一直到无穷大。有没有更好的方法教 Jarvis 处理任意数量的名字,而不用重载该sayHi()方法一百万次()?:/ 当然有!如果没有,您认为 Java 会成为世界上最流行的编程语言吗?;)

public class Jarvis {

   public void sayHi(String...names) {

       for (String name: names) {
           System.out.println("Good evening, " + name + ". How are you?");
       }
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark");
       System.out.println();
       jarvis.sayHi("Tony Stark", "Captain America");
   }
}
当 ( String... names ) 用作参数时,表示将向该方法传递一个 String 集合。我们不必事先指定会有多少,所以现在我们的方法更加灵活:

public class Jarvis {

   public void sayHi(String...names) {

       for (String name: names) {
           System.out.println("Good evening, " + name + ". How are you?");
       }
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark", "Captain America", "Black Widow", "Hulk");
   }
}
控制台输出: 晚上好,托尼·斯塔克。你好吗?晚上好,美国队长。你好吗?晚上好,黑寡妇。你好吗?晚上好,绿巨人。你好吗? 在方法内部,我们遍历所有参数并显示用名称格式化的短语。这里我们使用一个简化的for-each循环(您之前已经看到过)。在这里很完美,因为 ( String... names ) 符号实际上意味着编译器将所有传递的参数放入一个数组中。因此,我们可以使用变量就像我们处理数组一样,包括在循环中迭代它。另外,它可以处理任意数量的传递字符串!两人、十人,甚至一千人——这种方法对任何数量的客人都适用。比为所有可能性重载方法更方便,你不觉得吗?:) 这是方法重载的另一个例子。让我们给贾维斯一个printInfoFromDatabase()方法。它将显示有关数据库中某个人的信息。如果数据库表明某人是超级英雄或超级反派,我们将显示该信息:

public class Jarvis {

   public void printInfoFromDatabase (String bio) {

       System.out.println(bio);
   }

   public void printInfoFromDatabase(String bio, boolean isEvil, String nickname) {

       System.out.println(bio);
       if (!isEvil) {
           System.out.println("Also known as the superhero " + nickname);
       } else {
           System.out.println("Also known as the supervillain " + nickname);
       }
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.printInfoFromDatabase("Laura Palmer. Date of birth: July 22, 1972. Twin Peaks, Washington");
       System.out.println();
       jarvis.printInfoFromDatabase("Max Eisenhardt. Height: 15.6 ft. Weight: 189 lbs. ", true, "Magneto");
   }
}
输出: 劳拉·帕默。出生日期:1972 年 7 月 22 日。双峰,华盛顿 Max Eisenhardt。身高:15.6 英尺。体重:189 磅。也被称为 supervillain Magneto 所以,我们的方法的行为取决于我们传递给它的数据。这是另一个重点:参数的顺序很重要! 假设我们的方法接受一个字符串和一个数字:

public class Person {

   public static void sayYourAge(String greeting, int age) {
       System.out.println(greeting + " " + age);
   }

   public static void main(String[] args) {

       sayYourAge("My age is ", 33);
       sayYourAge(33, "My age is "); // Error!
   }
}
如果Person类的sayYourAge()方法将一个字符串和一个数字作为输入,那么这就是这些参数必须传递给方法的顺序!如果我们以不同的顺序传递它们,那么编译器将产生一个错误并且这个人将无法说出他的年龄。顺便说一句,我们在上一课中介绍的构造函数也是方法!您还可以重载它们(即创建多个具有不同参数集的构造函数)并且传递参数的顺序对它们来说也很重要。它们是真正的方法!:)

如何调用具有相似参数的方法

如您所知,null是 Java 中的关键字。了解这null既不是对象也不是数据类型非常重要。想象一下,我们有一个Person类和一个introduce()方法,它宣布了这个人的姓名和年龄。此外,年龄可以作为文本或数字传递。

public class Person {

   public void introduce(String name, String age) {
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public void introduce(String name, Integer age) {
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public static void main(String[] args) {

       Person alex = new Person();
       alex.introduce ("Alex", "twenty-one");

       Person mary = new Person();
       mary.introduce("Mary", 32);
   }
}
我们已经熟悉重载,所以我们知道这两种方法都将按它们应该的方式运行: 我的名字是 Alex。我今年二十一岁,我叫玛丽。我的年龄是 32 但是如果我们null作为第二个参数而不是字符串或数字传递会发生什么?

public static void main(String[] args) {

   Person victor = new Person();
   victor.introduce("Victor", null);// Ambiguous method call!
}
我们会得到一个编译错误!是什么原因造成的,“歧义”到底是什么?事实上,这一切都很简单。问题是我们有两个版本的方法:一个以 aString作为第二个参数,另一个以 anInteger作为第二个参数。但是 aString和 anInteger都可以是null!因为它们是引用类型,null所以是它们两者的默认值。这就是为什么在这种情况下编译器无法确定它应该调用哪个版本的方法。这个问题的解决方案非常简单。Null可以显式转换为特定的引用类型。 因此,当你调用一个方法时,你可以在括号中指出你想要的第二个参数的数据类型!编译器将理解您的“提示”并调用正确的方法:

public class Person {

   public void introduce(String name, String age) {
       System.out.println("Method with two strings!");
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public void introduce(String name, Integer age) {
       System.out.println("Method with a string and a number!");
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public static void main(String[] args) {

       Person victor = new Person();
       victor.introduce("Victor", (String) null);
   }
}
输出: 带有两个字符串的方法!我叫维克多。我的年龄是 null 请注意,如果数字参数是原始类型int,而不是 Integer 引用类型的实例,则不会出现这样的错误。

public class Person {

   public void introduce(String name, String age) {
       System.out.println("Method with two strings!");
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public void introduce(String name, int age) {
       System.out.println("Method with a string and a number!!");
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public static void main(String[] args) {

       Person victor = new Person();
       victor.introduce("Victor", null);
   }
}
你能猜出为什么吗?如果您确实猜到了原因,那就太好了!:) 因为原语不能null。现在编译器只有一个选择,即introduce()用两个字符串调用方法。这是每次调用该方法时将运行的方法版本。
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION