Menu
CoddyTech

Phương thức tổng quát

Thuộc phần Lập trình hướng đối tượng trong hành trình Java của Coddy. Bài học 55 trên 87.

Trong khi các lớp tổng quát cho phép cả lớp hoạt động với nhiều kiểu khác nhau, đôi khi bạn chỉ cần một phương thức tổng quát. Phương thức tổng quát khai báo tham số kiểu riêng, độc lập với các kiểu tổng quát ở cấp lớp.

Tham số kiểu xuất hiện trước kiểu trả về trong chữ ký phương thức:

public class Utility {
    public static <T> void printArray(T[] array) {
        for (T element : array) {
            System.out.println(element);
        }
    }
}

String[] names = {"Alice", "Bob"};
Integer[] numbers = {1, 2, 3};

Utility.printArray(names);    // Chạy được với String[]
Utility.printArray(numbers);  // Chạy được với Integer[]

Hãy chú ý đến <T> nằm giữa các từ bổ nghĩa và kiểu trả về. Phần này khai báo T là tham số kiểu của riêng phương thức này. Trình biên dịch suy ra kiểu thực tế từ các đối số bạn truyền vào.

Các phương thức tổng quát cũng có thể trả về kiểu tổng quát:

public static <T> T getFirst(T[] array) {
    if (array.length > 0) {
        return array[0];
    }
    return null;
}

String first = getFirst(new String[]{"a", "b"});  // Trả về "a"

Bạn có thể dùng nhiều tham số kiểu khi cần:

public static <K, V> void printPair(K key, V value) {
    System.out.println(key + ": " + value);
}

printPair("Age", 25);        // String và Integer
printPair(1, "First");       // Integer và String

Các phương thức tổng quát đặc biệt hữu ích trong những lớp tiện ích, nơi bạn cần các thao tác linh hoạt, có thể tái sử dụng mà không cần tạo lớp tổng quát.

challenge icon

Thử thách

Dễ

Hãy xây dựng một bộ công cụ tiện ích thể hiện tính linh hoạt của các phương thức tổng quát. Bạn sẽ tạo một lớp có các phương thức có thể tái sử dụng và hoạt động với mọi kiểu dữ liệu, qua đó cho thấy phương thức tổng quát có thể tồn tại độc lập với lớp tổng quát.

Bạn sẽ sắp xếp code trong hai tệp:

  • ArrayUtils.java: Tạo một lớp tiện ích chứa các phương thức tổng quát để làm việc với mảng. Lớp của bạn cần có ba phương thức tổng quát tĩnh:

    getLast - Một phương thức tổng quát nhận một mảng kiểu T và trả về phần tử cuối cùng. Nếu mảng rỗng, hãy trả về null.

    swap - Một phương thức tổng quát nhận một mảng kiểu T và hai chỉ số nguyên, sau đó hoán đổi các phần tử ở những vị trí đó. Phương thức này không trả về gì cả.

    printWithLabel - Một phương thức tổng quát có hai tham số kiểu K và V. Phương thức nhận một nhãn kiểu K và một giá trị kiểu V, sau đó in chúng theo định dạng: [label]: [value]

  • Main.java: Hãy sử dụng các phương thức tổng quát! Bạn sẽ nhận bốn đầu vào: hai từ (Strings) và hai số (số nguyên).

    Đầu tiên, tạo một mảng String[] chứa cả hai từ. Dùng getLast để lấy phần tử cuối cùng rồi in: Last word: [result]

    Tiếp theo, tạo một mảng Integer[] chứa cả hai số. Gọi swap để hoán đổi các phần tử ở chỉ số 0 và 1, rồi in: After swap: [first], [second]

    Cuối cùng, hãy minh họa phương thức tổng quát có hai tham số bằng cách gọi printWithLabel hai lần:

    • Một lần với từ đầu tiên làm nhãn và số đầu tiên làm giá trị
    • Một lần với số đầu tiên làm nhãn và từ thứ hai làm giá trị

Bạn sẽ nhận bốn đầu vào theo thứ tự: từ đầu tiên, từ thứ hai, số đầu tiên, số thứ hai.

Hãy chú ý cách mỗi phương thức khai báo (declare) (khai báo) tham số kiểu riêng bằng <T> hoặc <K, V> trước kiểu trả về. Trình biên dịch suy ra các kiểu thực tế từ những đối số bạn truyền vào, nên bạn không cần chỉ định chúng khi gọi phương thức!

Tự làm thử

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Đọc dữ liệu đầu vào
        String firstWord = scanner.nextLine();
        String secondWord = scanner.nextLine();
        int firstNumber = scanner.nextInt();
        int secondNumber = scanner.nextInt();
        
        // TODO: Tạo mảng String[] chứa cả hai từ
        
        // TODO: Dùng ArrayUtils.getLast để lấy phần tử cuối cùng
        // In ra: "Last word: [result]"
        
        // TODO: Tạo mảng Integer[] chứa cả hai số
        
        // TODO: Gọi ArrayUtils.swap để hoán đổi các phần tử ở chỉ số 0 và 1
        // In ra: "After swap: [first], [second]"
        
        // TODO: Gọi ArrayUtils.printWithLabel với firstWord làm nhãn và firstNumber làm giá trị
        
        // TODO: Gọi ArrayUtils.printWithLabel với firstNumber làm nhãn và secondWord làm giá trị
    }
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch Java online