Vì sao phải thêm default trong interface

Trong một lần tình cờ vào VOZ forums, có một bạn hỏi về Interface trong Java là gì?  Nó khác với Abstract Class chỗ nào? Tại sao phải dùng Interface, mặc dù nó chẳng rút gọn code đi tý nào, thậm chí còn dài hơn. Mặc dù có nhiều bạn trả lời cho chủ topic đó nhưng hầu hết là hiểu sai, hoặc chưa hiểu rõ bản chất của Interface trong Java.

Để các bạn có cái nhìn thấu đáo, hiểu rõ bản chất của Interface. Từ đó có thể ứng dụng Interface một cách chuẩn chỉ cho dự án của mình. Mình đã cho ra đời bài viết này.

Vì sao phải thêm default trong interface

Java Interface là gì? Có phải “bộ mặt” của Java?

Để hiểu một cách chính xác thì phải đọc khái niệm Interface của chính chủ Oracle:

In its most common form, an interface is a group of related methods with empty bodies.Oracle

Đến Oracle cũng không thể định nghĩa Interface một cách khoa học kiểu: Interface là xyz, bla bla. Nhưng chúng ta có thể hiểu một cách nôm na và chính xác như sau: Trong thế giới thực, chúng ta có vật (đồ vật, con vật…) và các hành vi của nó. Interface được sinh là để định nghĩa các hành vi của một nhóm vật.

Mình lấy ví dụ như sau: Một con mèo (đây là con vật) thì có các hành vi như: chạy, bắt chuột, ngủ…

Ta sẽ định nghĩa một Interface Cat như sau:

interface CatBehaviors { // Cách con mèo chạy với tốc độ void run(int speed); // Cách con mèo bắt chuột void catchMouse(int mouse); // Định nghĩa cách con mèo ngủ. void sleep(); }

Sau này chúng ta định nghĩa một con mèo thì tất nhiên nó sẽ phải các hành vi của con mèo, dù nó là mèo tam thể hay mèo vàng…

class Cat implements CatBehaviors { private String màu_lông; //Cách con mèo chạy với tốc độ void run(int speed){ ... } //Cách con mèo bắt chuột void catchMouse(int mouse){ ... } // Định nghĩa cách con mèo ngủ. void sleep(){ ... } }

Về học thuật thì Interface chính là khái niệm để hiện thực hóa triết lý đa hình trong lập trình hướng đối tượng. Cụ thể hơn thì mình sẽ giải thích ở phần sau của bài viết.

Interface Java cũng là một Abstract Class bao gồm các method được định nghĩa (nhưng nội dung của method thì không được viết cụ thể, người ta gọi là abstract method). Một Class sau này sẽ implements một Interface, đến lúc đó class mới viết cụ thể nội dung của các method được định nghĩa trong interface.

Trong Interface, ngoài abstract method, bạn hoàn toàn có thể thêm constants, static methods, nested interfaces (interface trong một interface) và default methods.

>> Đọc thêm: Học java ở đâu tốt nhất? Có cần phải đến trung tâm học lập trình?

Điểm giống – khác nhau giữa Interface và Abstract class:

Một interface về cơ bản hoàn toàn giống với abstract class. Một interface cũng có các abstract method và các method được thiết kế để implement ở các class khác. Việc implement này hoàn toàn giống với việc extend và override method trong Abstract class.

Về điểm khác nhau, thì mình thấy có 2 điểm chính:

  1. Về cách viết code: các method trong interface phải là empty method, tức là method không có nội dung, chỉ có tên hàm, tham số và kiểu dữ liệu trả về. Trong khi với abstract class thì bạn hoàn toàn có thể thêm abstract method hoặc method bình thường (là method có nội dung, logic bên trong body).
  2. Về mục đích sử dụng:
    • Interface là một chức năng mà bạn có thể thêm và bất kì class nào. Từ chức năng ở đây không đồng nghĩa với method (hay còn gọi là hàm).
    • Abstract class là một class cha cho tất cả các class có cùng bản chất. Bản chất ở đây được hiểu là kiểu, loại, nhiệm vụ của class.

Tại sao chúng ta cần Interface

Lý do chính là Java không hỗ trợ đa kế thừa. Do đó, bạn không thể kế thừa cùng một lúc nhiều class. Các class con không thể kế thừa các thuộc tính của nhiều class cha, vì nó dẫn đến bài toán Kim Cương (các bạn search Google để biết cái này nhé).

Để giải quyết vấn đề này, người ta mới cho ra đời Interface.  Để hiểu rõ hơn, chúng ta sẽ cùng nhau xem ví dụ dưới đây.

Bạn muốn thiết kế một Sở thú, gồm rất nhiều các con vật. Về cơ bản thì các con vật đều có các đặc điểm chung như: Có tên, có tiếng kêu, có chân (2 chân, 4 chân, hoặc 0 có chân nào…). Từ những đặc điểm chung đó bạn tạo một abstract class là: abstract class Animal

Vì sao phải thêm default trong interface

Tuy nhiên lại có một số loài lại biết bay, một số loài thì biết bơi. Và cái “dở” là loài biết bay lại không biết bơi. Do vậy, ta không thể để đặc điểm biết bay hay biết bơi trong class Animal được.

Đó là lý do chúng ta cần tạo 2 Interface khác nhau là Can_Fly và Can_Swim rồi xem class nào có thể implements từng cái thích hợp.

Vì sao phải thêm default trong interface

Đặc điểm chính của Java Interface

Bạn đọc đến chắc cũng đã hiểu phần nào về Interface trong Java rồi đúng không? Khi nào thì cần phải sử dụng Interface, và nó khác với Class thường chỗ nào.

Giờ mình sẽ tổng kết lại những đặc điểm chính mà bạn cần phải nhớ về Interface:

  • Các method được khai báo trong Interface phải là method rỗng.
  • Không thể tạo đối tượng từ Interface.
  • Một Class có thể implement một hoặc nhiều Interface.

Mình viết một đoạn code mình họa cho đỡ nhàm chán nhé.

public interface extInterface { public void method1(); public void method2(); } import java.util.Scanner; class Edureka implements extInterface{ public void method1(){ System.out.println("implementation of method1"); Scanner scanner = new Scanner(System.in); System.out.println("Enter number to find square root in Java : "); double square = scanner.nextDouble(); double squareRoot = Math.sqrt(square); System.out.printf("Square root of number: %f is : %f %n" , square, squareRoot); } public void method2(){ System.out.println("implementation of method2"); } public static void main(String arg[]){ extInterface obj = new Edureka(); obj.method1(); } }

Chạy đoạn code sẽ thu được kết quả:

implementation of method1 Enter number to find square root in Java : 16 Square root of number: 16.0 is : 4.0

Tổng kết

Như vậy là mình đã hoàn thành bài viết về Interface trong Java. Đọc đến đây, bạn đã “vỡ” ra được nhiều điều không? Nếu không thì… buồn ghê.

Các bạn nên nhớ, Interface chỉ là một công cụ, nó không phải là triết lý lập trình. Do vậy, khi ai đó nói tới lập trình hướng đối tượng, tới đa hình mà nói: Tính đa hình là interface. Thì không hẳn là đúng nhé. Nhớ này: Interface chỉ là một công cụ để thực hiện tính đa hình.

Các bạn có suy nghĩ thế nào về Interface? Hãy để lại bình luận ở bên dưới nhé.

Vì sao phải thêm default trong interface

Một Interface trong Java là một bản kế hoạch của class. Nó có chứa static constant và abstract method (phương thức trừu tượng)

Vì sao phải thêm default trong interface

Interface trong Java là một cơ chế để đạt được sự trừu tượng. Có thể chỉ có các phương thức trừu tượng trong Interface, không có phần thân phương thức. Nó được sử dụng để đạt được tính trừu tượng và đa kế thừa trong Java.

Nói cách khác, interface có thể có các phương thức trừu tượng và biến. Không có thân phương thức.

  • Interface cũng đại diện cho mối quan hệ IS-A
  • Interface không thể khởi tạo như classs
  • Từ phiên bản JAVA 8, chúng ta có thể có phương thức default và static trong interface
  • Từ JAVA 9 thì có thể có phương thức private trong interface

Tại sao nên sử dụng interface trong JAVA?

Chủ yếu có ba lý do để sử dụng giao diện. Chúng được đưa ra dưới đây.

  • Sử dụng Interface để đạt được sự trừu tượng.
  • Interface có thể hỗ trợ chúng ta đạt được đa kế thừa (Vì Java mặc định không hỗ trợ đa kế thừa thông qua class).
  • Nó có thể được sử dụng để đạt được Loose coupling.

Ghi chú: Loose coupling là có nghĩa là giữa các class gần như độc lập. Nếu class A biết về class B qua những gì đã thể hiện trong class B thì class A và class B là Loose coupling

Cách khai báo Interface trong JAVA

Một Interface trong Java được khai báo bằng cách sử dụng từ khóa interface. Nó cung cấp tổng thể trừu tượng; có nghĩa là tất cả các phương thức trong một interface được khai báo mà không có phần thân và tất cả các trường (field) là công khai (public), tĩnh (static) và cuối (final) cùng theo mặc định.

Một class triển khai một interface phải thực hiện tất cả các phương thức được khai báo trong interface.

Cú pháp của interface trong Java:

interface <interface_name>{ // Khai báo constant fields // Khai báo phương thức trừu tượng // ... }

Tham khảo: Cách đặt tên trong Java để biết cách đặt tên Interface tiêu chuẩn.

Cải tiến Interface trong JAVA 8

Kể từ Java 8, Interface có thể có các phương thức default và static sẽ được thảo luận sau.

Ghi chú: Trình biên dịch Java tự động thêm các từ khóa publicabstract trước phương thức trong Interface. Và nó cũng thêm các từ khóa public, staticfinal trước các data member. Do đó khi khai báo Interface chúng ta không cần thêm chúng.

Ví dụ chúng ta khai báo một interface thế này:

interface IInAn { int MIN = 5; void in(); }

Thì trình biên dịch sẽ hiểu / dịch như thế này:

interface IInAn { public static final int MIN = 5; public abstract void in(); }

Mối quan hệ giữa class và interface

Như trong hình bên dưới, một class mở rộng (extend) một class khác, một interface mở rộng (extend) một interface khác, nhưng một class sẽ triển khai (implements) một interface.

Vì sao phải thêm default trong interface

Lưu ý: Nếu bạn đang tích cực học Java để đi thực tập, đi làm. Hãy tham khảo ngay khóa học LẬP TRÌNH JAVA WEB tại NIIT – ICT Hà Nội để được hướng dẫn bởi chuyên gia doanh nghiệp, đào tạo theo nhu cầu thực tiễn, tuyển dụng ngay cuối khóa học!

Ví dụ về Interface trong JAVA

Trong ví dụ này, Interface IInAn chỉ có một phương thức và việc triển khai nó được cung cấp trong class A6.

// Khai báo Interface interface IInAn{ // Khai báo phương thức trừu tượng void inThongTin(); } // Triển khai interface class A6 implements IInAn{ // Viết khai triển cụ thể cho phương thức trừu tượng public void inThongTin(){ System.out.println("Xin Chào"); } public static void main(String args[]){ A6 a6 = new A6(); a6.inThongTin(); } }

Kết quả khi chạy chương trình:

Xin chào

Tiếp tục một ví dụ khác về interface trong Java.

Trong ví dụ này, Interface IVeHinh chỉ có một phương thức ve(). Việc triển khai nó được cung cấp bởi các lớp HinhChuNhat và HinhTron.

Trong một kịch bản thực tế, một interface sẽ được định nghĩa bởi người khác, việc triển khai nó sẽ khác nhau bởi các lập trình viên khác nhau. Phần triển khai được ẩn bởi người dùng sử dụng interface.

// Khai báo Interface: User đầu tiên interface IVeHinh{ void ve(); } // Triển khai: User thứ hai class HinhChuNhat implements IVeHinh{ public void ve(){ System.out.println("Vẽ hình chữ nhật..."); } } class HinhTron implements IVeHinh{ public void ve(){ System.out.println("Vẽ hình tròn..."); } } // Sử dụng interface: User thứ ba class TestInterface1{ public static void main(String args[]){ IVeHInh d = new HinhTron(); d.ve(); } }

Kết quả khi chạy chương trình:

Vẽ hình tròn...

Hãy thử xem một ví dụ khác về interface java cung cấp việc triển interface INganHang

interface INganHang{ float rateOfInterest(); } class Agri implements INganHang{ public float laiSuat(){ return 0.07; } } class VCB implements INganHang{ public float laiSuat(){ return 0.08; } } class TestInterface2{ public static void main(String[] args){ INganHang nganHang = new VCB(); System.out.println("Lãi suất: " + nganHang.laiSuat() * 100 + "%"); } }

Kết quả khi chạy chương trình:

Lãi suất: 8%

Đạt được tính đa kế thừa trong Java thông qua interface

Nếu một lớp Java triển khai nhiều interface hoặc interface mở rộng nhiều interface, nó được gọi là đa kế thừa.

Vì sao phải thêm default trong interface

Ví dụ:

interface IInAn{ void inThongTin(); } interface IHienThi{ void hienThi(); } // Đa kế thừa class A7 implements IInAn, IHienThi{ public void inThongTin(){ System.out.println("Xin chào"); } public void hienThi(){ System.out.println("Hiển thị bản xem trước"); } public static void main(String args[]){ A7 a7 = new A7(); a7.inThongTin(); a7.hienThi(); } }

Kết quả khi chạy chương trình:

Xin chào Hiển thị bản xem trước

Câu hỏi: Đa kế thừa không được hỗ trợ thông qua class trong java, nhưng tại sao nó có thể được thực hiện bởi một interface?

Như chúng ta đã giải thích trong chương kế thừa trong Java, Java không hỗ trợ đa kế thừa class vì sự mơ hồ.

Tuy nhiên, vì đa kế thừa thông qua interface không mơ hồ nên nó được hỗ trợ. Việc triển khai của nó được cung cấp bởi class thực thi. Ví dụ:

interface IInAn{ void inThongTin(); } interface IHienThi{ void hienThi(); } class TestInterface3 implements IInAn, IHienThi{ public void inThongTin(){ System.out.println("Xin chào"); } public static void main(String args[]){ TestInterface3 obj = new TestInterface3(); obj.inThongTin(); } }

Kết quả khi chạy chương trình:

Xin chào

Kế thừa interface

Trong Java, một class triển khai (implements) một interface, nhưng một interface này mở rộng (extends) một interface khác.

interface IInAn{ void inThongTin(); } interface IHienThi extends IInAn{ void hienThi(); } class TestInterface4 implements Showable{ public void inThongTin(){ System.out.println("Xin chào"); } public void hienThi(){ System.out.println("Hiển thị bản xem trước"); } public static void main(String args[]){ TestInterface4 obj = new TestInterface4(); obj.inThongTin(); obj.hienThi(); } }

Kết quả khi chạy chương trình:

Xin chào Hiển thị bản xem trước

Phương thức default của Java 8 trong interface

Kể từ Java 8, chúng ta có thể có thân phương thức trong interface. Nhưng chúng ta cần đặt nó thành phương thức default. Hãy xem một ví dụ:

interface IVeHinh{ void ve(); default void msg(){ System.out.println("Phương thức default"); } } class HinhChuNhat implements IVeHinh{ public void ve(){ System.out.println("Vẽ hình chữ nhật"); } } class TestInterfaceDefault{ public static void main(String args[]){ IVeHinh hinhChuNhat = new HinhChuNhat(); hinhChuNhat.ve(); hinhChuNhat.msg(); } }

Kết quả khi chạy chương trình:

Vẽ hình chữ nhật Phương thức default

Câu hỏi: Interface được đánh dấu (marker) hoặc được gắn thẻ (tagged) là gì?

Một interface không có data member nào được gọi là marker interface hoặc tagged interface.

Ví dụ: Serializable, Cloneable, Remote , v.v. Chúng được sử dụng để cung cấp một số thông tin cần thiết cho JVM để JVM có thể thực hiện một số hành vi.

Interface lồng nhau trong Java

Một interface có thể có một interface khác được gọi là interface lồng nhau (Nested Interface). Chúng ta sẽ tìm hiểu nó một cách chi tiết trong chương Nested Class. Ví dụ:

interface IInAn{ void in(); // Interface được lồng trong interface khác interface IThongTinInAn{ void thongTin(); } }

Như vậy, qua bài viết này, mình đã hướng dẫn bạn tìm hiểu về interface trong Java, và cùng với các ví dụ đơn giản hi vọng bạn hiểu được cách khai báo, triển khai và đạt được tính đa kế thừa thông qua interface.

Chúc bạn học tốt!