Interface và Abstract class

Abstract class (lớp trừu tượng):


Abstract class trong Java tương tự như Interface ngoại trừ việc nó có thể chứa cách triển khai phương thức mặc định. Một Abstract class có thể có abstract method không có body và nó có thể có phương thức đc triển khai (methods with implementation)

keyword khởi tạo 1 lớp và phương thức trừu tượng: abstract

Important points (điểm quan trọng):

1. Từ khóa abstract sử dụng để tạo lớp trừu tượng trong Java

2. Abstract class không thể được khởi tạo

3. Có thể sử dụng abstract keyword để tạo phương thức trừu tượng không có phần thân

package com.journaldev.design;


//abstract class

public abstract class Person {

private String name;

private String gender;

public Person(String nm, String gen){

this.name=nm;

this.gender=gen;

}

//abstract method

public abstract void work();

@Override

public String toString(){

return "Name="+this.name+"::Gender="+this.gender;

}


public void changeName(String newName) {

this.name = newName;

}

}



package com.journaldev.design;


public class Employee extends Person {

private int empId;

public Employee(String nm, String gen, int id) {

super(nm, gen);

this.empId=id;

}


@Override

public void work() {

if(empId == 0){

System.out.println("Not working");

}else{

System.out.println("Working as employee!!");

}

}

public static void main(String args[]){

//coding in terms of abstract classes

Person student = new Employee("Dove","Female",0);

Person employee = new Employee("Pankaj","Male",123);

student.work();

employee.work();

//using method implemented in abstract class - inheritance

employee.changeName("Pankaj Kumar");

System.out.println(employee.toString());

}


}

Interface:

  • Khái niệm Interface:

    • Interface là đoạn mã dùng để tạo ra một giao diện trong Java.
    • Chúng ta không thể tạo đối tượng (instantiate) từ một interface trong Java.
  • Abstraction tuyệt đối:

    • Interface cung cấp sự trừu tượng hóa tuyệt đối. Trong bài viết trước, chúng ta đã tìm hiểu về các lớp trừu tượng (abstract classes) để cung cấp trừu tượng hóa, nhưng lớp trừu tượng có thể có các phương thức được triển khai sẵn (method implementations), còn interface thì không thể.
  • Constructor:

    • Interface không có constructor vì chúng ta không thể tạo đối tượng từ chúng và interface không thể có phương thức với phần thân (body).
  • Thuộc tính của Interface:

    • Theo mặc định, bất kỳ thuộc tính nào của interface đều là public, static, và final. Vì vậy, chúng ta không cần cung cấp các bộ điều khiển truy cập (access modifiers) cho các thuộc tính, nhưng nếu có thì trình biên dịch cũng không báo lỗi.
  • Phương thức của Interface:

    • Theo mặc định, các phương thức trong interface là trừu tượng (abstract) và công khai (public). Điều này hoàn toàn hợp lý vì các phương thức này không có thân và các lớp con sẽ cung cấp phần triển khai (implementation) cho các phương thức này.
  • Kế thừa Interface:

    • Một interface không thể mở rộng (extend) bất kỳ lớp nào nhưng có thể mở rộng một interface khác. Ví dụ: public interface Shape extends Cloneable{} là một ví dụ về interface mở rộng interface khác.
    • Thực tế, Java hỗ trợ đa kế thừa (multiple inheritance) trong các interface, có nghĩa là một interface có thể mở rộng nhiều interface khác.
  • Từ khóa implements:

    • Từ khóa implements được sử dụng bởi các lớp để triển khai một interface.
    • Một lớp triển khai một interface phải cung cấp phần triển khai cho tất cả các phương thức của interface, trừ khi lớp đó là lớp trừu tượng.
  • Lập trình theo Interface:

    • Chúng ta nên luôn cố gắng viết chương trình theo hướng interface thay vì các triển khai cụ thể. Điều này giúp chúng ta biết trước rằng các lớp triển khai sẽ luôn cung cấp phần triển khai cần thiết và nếu trong tương lai có bất kỳ triển khai tốt hơn nào, chúng ta có thể dễ dàng thay thế nó.
  •    


    Java Interface Benefits ( Lợi ích sử dụng Java Interface)
            
  • Hợp đồng cho các lớp triển khai:

    • Interface cung cấp một hợp đồng (contract) cho tất cả các lớp triển khai. Điều này có nghĩa là tất cả các lớp triển khai một interface phải cung cấp phần triển khai cho tất cả các phương thức được định nghĩa trong interface đó. Vì vậy, việc viết mã theo hướng interface đảm bảo rằng các lớp triển khai không thể loại bỏ các phương thức mà chúng ta đang sử dụng. Điều này giúp bảo vệ và duy trì tính nhất quán của mã nguồn.
  • Định nghĩa kiểu và tạo cấu trúc phân cấp:

    • Interface là một điểm khởi đầu tốt để định nghĩa kiểu (Type) và tạo cấu trúc phân cấp cao trong mã nguồn của chúng ta. Bằng cách định nghĩa các interface, chúng ta có thể xác định rõ ràng các kiểu đối tượng và mối quan hệ giữa chúng trong hệ thống, giúp mã nguồn dễ hiểu và dễ bảo trì hơn.
  • Hỗ trợ đa kế thừa:

    • Trong Java, một lớp có thể triển khai nhiều interface. Điều này khác với việc kế thừa lớp (class inheritance) khi một lớp chỉ có thể kế thừa một lớp cha duy nhất. Vì vậy, việc sử dụng interface làm lớp cha trong hầu hết các trường hợp sẽ tốt hơn, bởi nó cho phép chúng ta tận dụng lợi ích của đa kế thừa, giúp thiết kế hệ thống linh hoạt hơn và dễ mở rộng hơn.



    So sánh Interface và Abstract Class:

        Sự khác nhau chính giữa Interface và Abstract Class trong Java
    1. Phương thức:

      • Phương thức của một interface trong Java mặc định là trừu tượng (abstract) và không thể có phần triển khai.
      • Ngược lại, một lớp trừu tượng (abstract class) trong Java có thể có các phương thức thể hiện (instance methods) và các phương thức này có thể có phần triển khai mặc định.
    2. Biến:

      • Các biến được khai báo trong một interface Java mặc định là hằng số (final).
      • Một lớp trừu tượng có thể chứa các biến không phải là hằng số (non-final).
    3. Thành viên:

      • Các thành viên của một interface Java mặc định là công khai (public).
      • Một lớp trừu tượng có thể có các thành viên với các bộ điều khiển truy cập khác nhau như private, protected, v.v.
    4. Từ khóa:

      • Một interface Java được triển khai (implemented) bằng cách sử dụng từ khóa “implements”.
      • Một lớp trừu tượng Java được mở rộng (extended) bằng cách sử dụng từ khóa “extends”.
    5. Kế thừa:

      • Một interface chỉ có thể mở rộng một interface khác trong Java.
      • Một lớp trừu tượng có thể mở rộng một lớp Java khác và triển khai nhiều interface.
    6. Đa kế thừa:

      • Một lớp Java có thể triển khai nhiều interface nhưng chỉ có thể mở rộng một lớp trừu tượng.
    7. Tính thể hiện:

      • Interface hoàn toàn trừu tượng và không thể được tạo thể hiện (instantiated).
      • Một lớp trừu tượng cũng không thể được tạo thể hiện, nhưng có thể được gọi nếu nó chứa phương thức main().
    8. Hiệu suất:

      • So với các lớp trừu tượng trong Java, các interface trong Java chậm hơn vì cần có sự gián tiếp bổ sung (extra indirection).

    Tóm lại, việc sử dụng interface hay lớp trừu tượng phụ thuộc vào yêu cầu cụ thể của thiết kế hệ thống. Interface cung cấp sự trừu tượng hóa hoàn toàn và linh hoạt trong việc triển khai nhiều interface, trong khi lớp trừu tượng cung cấp khả năng chia sẻ triển khai mặc định và duy trì trạng thái thông qua các biến không phải là hằng số.

    Abstract class (lớp trừu tượng):