Giật tít tý cho một số thanh niên hoang mang 😀

Các đánh giá trong phần này chỉ dựa trên quan điểm cá nhân và mang tính chất tham khảo. Các bạn có thể bình luận góp ý nếu thấy phần nào không hợp lý 🙂

Vâng. Tất nhiên Interface và Abstract không phải là một rồi, nó có điểm khác nhau, nhưng thực tế không ít sinh viên mới tốt nghiệp và kể cả 1 số đã đi làm vẫn trả lời lơ mơ khi đi phỏng vấn. Một câu hỏi kinh điển và trường kỳ quen thuộc nhưng vẫn hiệu quả trong các buổi phỏng vấn để đánh giá kiến thức cơ bản của thí sinh.

Giờ vào chi tiết. Đầu tiên là So sánh Interface và Abstract.
Chỉ cần tìm kiếm trên Google với từ khóa “Interface và Abstract” là đã có 1 loạt các kết quả dạng bảng đối chiếu để so sánh 2 cái này, vì vậy mình sẽ không viết lại cái đó nữa mà giải thích sâu hơn về 1 số điểm khác biệt lớn

Abstract class Interface
Mục đích sử dụng của Abstract thiên về tính chất/đặc điểm: Nó là cái gì, nó có cái gì, nó như thế nào! Mục đích sử dụng của Interface thiên về hành động: Nó có thể làm cái gì!
Abstract class không hỗ trợ đa kế thừa. Interface hỗ trợ cách thức thay thế cho đa kế thừa
Abstract class có phương thức abstract (không có thân phương thức) và phương thức non-abstract (có thân phương thức). Interface chỉ có phương thức abstract. Từ Java 8, nó có thêm phương thức default (có thân phương thức)
Abstract class có các biến final, non-final, static and non-static. Interface chỉ có các biến static và final.
Abstract method trong Abstract class có thể là public hoặc protected Abstract method trong Interface chỉ có thể là public
(*Từ Java 9 cho phép thêm method privateprivate static vào Interface)

Interface hỗ trợ đa kế thừa!

Xin đính chính lại, đây là 1 mệnh đề sai. Bởi vì bản chất Java (và cả C#) đều không hỗ trợ đa kế thừa. Do nhận thấy các vấn đề quá rối rắm của các ngôn ngữ đàn anh (C++ / Pascal) khi hỗ trợ đa kế thừa, gây ra việc con sinh ra có 2 bố mà có những tính xấu không ông nào nhận nó kế thừa từ mình, mà những tính tốt của con thì ông nào cũng tranh. Vì vậy Java đã tuyên bố không hỗ trợ đa kế thừa để giải quyết mâu thuẫn. Nhưng vì nhu cầu thực tế nên Java đã sinh ra thể loại mới để an ủi: Interface ra đời chỉ là giải pháp thay thế cho đa kế thừa. Và đây là điểm khác biệt lớn nhất của Interface và Abstract.

Interface có định nghĩa method (viết thân hàm) được không?

Từ phiên bản Java 8 trở đi thì câu trả lời là có, ta có thể thực hiện điều này với các phương thức có từ khóa default. Việc này làm cho Interface gần giống Abstract và còn có thể thay thế cho Abstract ở 1 số trường hợp. Nhưng tại sao đến tận phiên bản Java 8 mới cho phép điều này? Theo mình thì ban đầu khi mới xây dựng Interface cho Java, vì mang lại cho class khả năng implement nhiều interface nên việc tìm method override từ interface nào phải bằng cách duyệt từng interface thay vì chỉ cần duyệt cha như abstract, thao tác này có phần làm cho hiệu năng xử lý bị giảm đi nên interface không được tích hợp định nghĩa method.

Nhưng với Java 8, (theo mình) nhiều thuật toán xử lý đã được tối ưu và hạ tầng phần cứng hiện nay cũng đã tốt hơn rất nhiều nên Java cho phép định nghĩa phương thức trong Interface.

Hai điểm khác biệt tiếp theo chỉ là quy định đơn giản, không có nhiều ý nghĩa đặc biệt nên mình chỉ liệt kê vào và không giải thích nhiều.

Vậy khi nào thì sử dụng Interface, khi nào sử dụng Abstract?

Theo mục đích và thói quen sử dụng thì mình thường dùng 2 cái này vào 1 số trường hợp sau

Abstract:

Các class common, dạng component đóng gói dùng chung và cho phép mở rộng. Hoặc dựng 1 khung quy trình nghiệp vụ chức năng

Ví dụ 1 quy trình xuất file báo cáo

abstract class ReportCommon {
    /**
     * Lấy tham số, điều kiện tìm kiếm cho báo cáo
     */
    public abstract void loadParameter();
    /**
     * Xử lý tham số, chuẩn bị sql query
     */
    public abstract void beforeQuery();
    /**
     * Tinh chỉnh dữ liệu sau khi query
     */
    public abstract void afterQuery();
    /**
     * Xuất file báo cáo
     */
    public abstract void exportFile();
    /**
     * Phương thức xử lý chính
     */
    public void mainProcess() {
        loadParameter();
        beforeQuery();
        //todo: Phần thực thi query, xử lý lấy dữ liệu báo cáo,...
        afterQuery();
        exportFile();
    }
}

Với bất kỳ 1 báo cáo nào, chỉ cần extends common trên sau đó thực hiện cài đặt các phương thức abstract theo nghiệp vụ riêng. Với 1 hệ thống có khoảng vài chục báo cáo thì việc nhu cầu thay đổi cách thức xuất báo cáo cũng chỉ cần chỉnh sửa 1 file common duy nhất

Interface:

Nếu bạn cần triển khai 1 webservice, API, hay đơn giản nội tại 1 hệ thống là 1 dạng listener ([Java] Phần 1: Interface với cách tạo Listener lắng nghe sự kiện và Event kích hoạt sự kiện), hay điển hình 1 trường hợp cần multi-implement thì Interface là 1 lựa chọn phù hợp nhất.

Hoặc nếu muốn xây dựng 1 hệ thống mở, cho phép thiết kế bổ sung plugins (dạng extension chrome / add-ons firefox) thì nên sử dụng Interface

Kết: Hy vọng sau phần này, các bạn sẽ thấm thêm một chút để tự tin hơn khi gặp câu hỏi phỏng vấn ở mức cơ bản này!

One Reply to “[Java] Phần 4: Interface và Abstract là một?”

Bình luận