1. Truyền đối số

Và bây giờ niềm vui bắt đầu. Có thể bạn đã biết từ các phương thức như vậy System.out.println()chúng ta có thể truyền đối số cho các phương thức. Khi chúng ta ở bên trong phương thức, chúng ta gọi chúng là tham số. Trên thực tế, các tham số nâng cao đáng kể lợi ích mà chúng ta nhận được từ việc tạo và sử dụng các phương thức.

Làm thế nào để chúng ta khai báo một phương thức với các tham số? Nó thực sự khá đơn giản:

public static void name(parameters)
{
  method body
}

Đâu name là tên duy nhất của phương thức và method body đại diện cho các lệnh tạo nên phương thức. Và parameters là trình giữ chỗ cho các tham số của phương thức, được phân tách bằng dấu phẩy. Hãy mô tả mẫu này chi tiết hơn:

public static void name(Type1 name1, Type2 name2, Type3 name3)
{
  method body
}

Ví dụ:

Mã số Giải trình
public static void print(String str)
{
}
Phương printthức được khai báo với một tham số:
String str
public static void print(String str, int count)
{
}
Phương printthức được khai báo với hai tham số:
String str
int count
public static void write(int x, int y)
{
}
Phương writethức được khai báo với hai tham số:
int x
int y

Nếu chúng ta không muốn phương thức có tham số, thì chúng ta chỉ cần để trống dấu ngoặc đơn.

Tham số là các biến đặc biệt trong một phương thức. Với sự giúp đỡ của họ, bạn có thể truyền các giá trị khác nhau cho phương thức khi nó được gọi.

Ví dụ: hãy viết một phương thức hiển thị một chuỗi văn bản theo một số lần nhất định.

Bạn đã biết cách viết code để hiển thị nhiều lần một chuỗi lên màn hình. Nhưng bạn nên in chuỗi nào? Và bao nhiêu lần? Đó là những gì chúng ta cần các thông số cho.

Đoạn mã thực hiện điều này sẽ trông như thế này:

Mã số Giải trình
class Solution
{
   public static void printLines(String text, int count)
   {
     for (int i = 0; i < count; i++)
       System.out.println(text);
   }

   public static void main(String[] args)
   {
     printLines("Hi", 10);
     printLines("Bye", 20);
   }
}


Chúng tôi đã khai báo printLinesphương thức với các tham số sau:
String text, int count
Phương thức hiển thị Chuỗi text countlần





Chúng tôi gọi printLinesphương thức với các tham số khác nhau

Mỗi khi một phương thức được gọi, các tham số của nó được gán các giá trị đã truyền và chỉ khi đó chúng ta mới bắt đầu thực thi các lệnh bên trong phương thức.


2. Lập luận

Tôi muốn thu hút sự chú ý của bạn nhiều hơn một chút đến việc gọi một phương thức có tham số.

Các giá trị được truyền cho phương thức thường được gọi là đối số khi chúng được truyền cho phương thức.

Hãy xem xét một ví dụ khác:

Mã số Giải trình
class Solution
{
   public static void printLines(String text, int count)
   {
     for (int i = 0; i < count; i++)
       System.out.println(text);
   }

   public static void main(String[] args)
   {
     printLines("Hi", 10);
     printLines("Bye", 20);
   }
}


Chúng ta đã khai báo printLinesphương thức với các tham số sau:
String text, int count
Phương thức hiển thị số text countlần Chuỗi




Chúng ta gọi printLinesphương thức với các đối số sau:
text = "Hi"; count = 10;
text = "Bye"; count = 20;

Khi printLines phương thức được gọi lần đầu tiên, các tham số của nó được gán các giá trị sau:
String text = "Hi", int count = 10.

Khi printLinesphương thức được gọi lần thứ hai, các tham số của nó được gán các giá trị khác nhau:
String text = "Bye", int count = 20.

Các tham số không hơn không kém các biến được gán các giá trị nhất định khi một phương thức được gọi. Bản thân các giá trị "Hi", "Bye", 10, và 20được gọi là các đối số."


3. Xung đột tên biến khi gọi phương thức

Các biến có thể được sử dụng làm đối số của phương thức. Điều này đơn giản và dễ hiểu, nhưng nó có khả năng gây ra một số khó khăn. Hãy quay lại ví dụ tương tự, nhưng lần này chúng ta sẽ chuyển các đối số thành các biến riêng biệt:

Mã số Giải trình
class Solution
{
   public static void printLines(String text, int count)
   {
     for (int i = 0; i < count; i++)
       System.out.print(text);
   }

   public static void main(String[] args)
   {
     String str = "Hi";
     int n = 10;
     printLines(str, n);
   }
}


Chúng ta đã khai báo printLinesphương thức với các tham số sau:
String text, int count
Phương thức hiển thị số text countlần Chuỗi







Chúng ta gọi printLinesphương thức với các đối số sau:
text = str;
count = n;

Cho đến nay, rất tốt: chúng tôi có một strbiến. Giá trị của nó được gán cho texttham số khi phương thức được gọi. Chúng tôi có một nbiến. Giá trị của nó được gán cho counttham số khi phương thức được gọi." Cho đến nay, mọi thứ đã rõ ràng.

Bây giờ hãy đổi tên các biến của chúng ta trong mainphương thức:

Mã số Giải trình
class Solution
{
   public static void printLines(String text, int count)
   {
     for (int i = 0; i < count; i++)
       System.out.print(text);
   }

   public static void main(String[] args)
   {
     String text = "Hi";
     int count = 10;
     printLines(text, count);
   }
}


Chúng ta đã khai báo printLinesphương thức với các tham số sau:
String text, int count
Phương thức hiển thị số text countlần Chuỗi







Chúng ta gọi printLinesphương thức với các đối số sau:
text = text;
count = count;

Hãy chú ý đến hai điều

Đầu tiên: chúng ta có các biến có cùng tên trong các phương thức khác nhau. Đây là các biến khác nhau (chúng tôi cố tình mô tả chúng bằng các màu khác nhau). Mọi thứ hoạt động giống như trong ví dụ trước, trong đó các biến trong mainphương thức được đặt tên strn.

Thứ hai: Không có gì kỳ diệu xảy ra khi phương thức được gọi. Các tham số được gán đơn giản là các giá trị đối số. Bất kể chúng là số, chuỗi, biến hay biểu thức.

Sau khi chúng tôi đổi tên các biến trong phương thức chính, không có gì thay đổi. Chúng là các biến khác nhau trong các phương pháp khác nhau trước đây và vì vậy chúng vẫn còn. Không có kết nối kỳ diệu giữa text và text các biến.



4. Truyền tham chiếu đến các phương thức

Tôi hy vọng bạn đã hiểu mọi thứ từ bài học trước, bởi vì bây giờ chúng ta sẽ xem lại việc truyền đối số cho các phương thức, chỉ là chúng ta sẽ tìm hiểu sâu hơn.

Như bạn đã biết, một số biến Java không lưu trữ các giá trị mà thay vào đó là một tham chiếu, tức là địa chỉ của khối bộ nhớ chứa các giá trị. Đây là cách hoạt động của biến chuỗi và biến mảng.

Khi bạn gán một biến mảng khác cho một biến mảng, điều gì sẽ xảy ra? Đúng rồi. Hai biến bắt đầu đề cập đến cùng một không gian trong bộ nhớ:

Truyền tham chiếu đến các phương thức

Và điều gì xảy ra nếu một trong các biến này là tham số của phương thức?

Mã số Giải trình
class Solution
{
   public static void printArraySum(int[] data)
   {
     int sum = 0;
     for (int i = 0; i < data.length; i++)
       sum = sum + data[i];
     System.out.println(sum);
   }

   public static void main(String[] args)
   {
     int[] months = {31, 28, 31, 30, 31, 30, 31, 31, 30};
     printArraySum(months);
   }
}


Phương printArraySumthức tính tổng các số trong mảng truyền vào và hiển thị ra màn hình

Điều tương tự cũng xảy ra: data tham số sẽ chứa tham chiếu đến cùng vùng bộ nhớ với monthsbiến. Khi phương thức được gọi, một nhiệm vụ đơn giản xảy ra: .data = months

Và vì cả hai biến đều tham chiếu đến cùng một vùng bộ nhớ lưu trữ một số nguyên, nên printArraySum phương thức này không chỉ có thể đọc các giá trị từ mảng mà còn có thể thay đổi chúng!

Ví dụ: chúng ta có thể viết phương thức của riêng mình để điền vào một mảng hai chiều có cùng giá trị. Đây là cách nó có thể trông:

Mã số Giải trình
class Solution
{
   public static void fill(int[][] data, int value)
   {
     for (int i = 0; i < data.length; i++)
     {
       for (int j = 0; j < data[i].length; j++)
         data[i][j] = value;
     }
  }

   public static void main(String[] args)
   {
     int[][] months = {{31, 28}, {31, 30, 31}, {30, 31, 31}};
     fill (months, 8);
   }
}


Phương fill thức lặp lại trên mọi ô trong mảng hai chiều đã truyền và gán valuecho chúng.








Chúng tôi tạo một mảng hai chiều.
Chúng tôi điền vào toàn bộ mảng với số 8.


5. Các phương thức trùng tên

Bây giờ, hãy quay lại tên phương thức một lần nữa.

Các tiêu chuẩn Java yêu cầu tất cả các phương thức trong cùng một lớp phải có tên duy nhất. Nói cách khác, không thể khai báo hai phương thức có tên giống hệt nhau trong cùng một lớp.

Khi các phương thức được so sánh về tính giống nhau, không chỉ các tên được tính đến mà còn cả các loại tham số ! Lưu ý rằng tên của các tham số không được tính đến . Ví dụ:

Mã số Giải trình
void fill(int[] data, int value) {
}
void fill(int[][] data, int value) {
}
void fill(int[][][] data, int value)  {
}
Ba phương pháp này là những phương pháp khác nhau . Chúng có thể được khai báo trong cùng một lớp.
void print(String str) {
}
void print(String str, String str2) {
}
void print(int val) {
}
void print(double val) {
}
void print() {
}
Mỗi phương pháp trong số năm phương pháp này được coi là khác nhau . Chúng có thể được khai báo trong cùng một lớp.
void sum(int x, int y) {
}
void sum(int data, int value) {
}
Hai phương thức này được coi là giống nhau , nghĩa là chúng không thể được khai báo trong cùng một lớp.

Tại sao một số phương pháp được coi là giống nhau , trong khi những phương pháp khác thì khác ? Và tại sao các tên tham số không được tính đến khi xác định tính duy nhất của một phương thức?

Tại sao sự độc đáo lại cần thiết? Vấn đề là khi trình biên dịch biên dịch một chương trình, nó phải biết chính xác bạn định gọi phương thức nào ở bất kỳ vị trí cụ thể nào.

Ví dụ, nếu bạn viết , trình biên dịch thông minh và sẽ dễ dàng kết luận rằng bạn định gọi phương thức ở đây với một tham số.System.out.println("Hi")println()String

Nhưng nếu bạn viết , trình biên dịch sẽ thấy lời gọi phương thức có tham số.System.out.println(1.0)println()double

Khi một phương thức được gọi, trình biên dịch đảm bảo rằng kiểu của các đối số khớp với kiểu của tham số. Nó không chú ý đến tên của các đối số. Trong Java, tên tham số không giúp trình biên dịch xác định phương thức nào sẽ gọi. Và đó là lý do tại sao chúng không được tính đến khi xác định tính duy nhất của một phương pháp.

Tên của một phương thức và các loại tham số của nó được gọi là chữ ký của phương thức . Ví dụ,sum(int, int)

Mỗi lớp phải có các phương thức có chữ ký duy nhất thay vì các phương thức có tên duy nhất.