Java Interfaces

12 tháng 09, 2022 - 3366 lượt xem

Java Interfaces

Người dịch: Nguyễn Thành Trung - Học viên lớp Java08
Email liên hệ: nguyenthanhtrung.nlk58@gmail.com
Bài viết gốc: https://www.baeldung.com/java-interfaces

1. Tổng quan

Trong bài này, chúng ta sẽ nói về các interface trong Java. Chúng ta cũng sẽ xem cách Java sử dụng chúng để triển khai tính đa hình và nhiều tính kế thừa.

2. Interface trong Java là gì?

Trong Java, interface là một kiểu trừu tượng chứa một tập hợp các phương thức và các biến hằng số. Nó là một trong những khái niệm cốt lõi trong Java và được sử dụng để đạt được tính trừu tượng, đa hìnhđa kế thừa .

Hãy xem một ví dụ đơn giản về interface trong Java:

public interface Electronic {

    // Constant variable
    String LED = "LED";

    // Abstract method
    int getElectricityUse();

    // Static method
    static boolean isEnergyEfficient(String electtronicType) {
        if (electtronicType.equals(LED)) {
            return true;
        }
        return false;
    }

    //Default method
    default void printDescription() {
        System.out.println("Electronic Description");
    }
}

Chúng ta có thể triển khai một interface trong một lớp Java bằng cách sử dụng từ khóa implements.

Tiếp theo, hãy cũng tạo một lớp Computer thực hiện Electronic interface mà chúng ta vừa tạo:

public class Computer implements Electronic {

    @Override
    public int getElectricityUse() {
        return 1000;
    }
}

2.1. Quy tắc tạo Interface

Trong một interface, chúng ta được phép sử dụng:

  • Biến hằng số
  • Phương thức trừu tượng
  • Phương thức static
  • Phương thức mặc dịnh

Chúng ta cũng nên nhớ rằng:

  • Chúng ta không thể khởi tạo interface trực tiếp.
  • Một interface có thể rỗng, không có phương thức hoặc biến trong đó.
  • Chúng ta không thể sử dụng final trong định nghĩa interface, vì nó sẽ dẫn đến lỗi trình biên dịch.
  • Tất cả các khai báo interface phải có public hoặc default access modifier; abstract modifier sẽ được trình biên dịch tự động thêm vào.
  • Một phương thức interface không thể protected hoặc final.
  • Trước Java 9, các phương thức interface không thể là private, tuy nhiên, Java 9 đã giới thiệu khả năng xác định private methods trong interface.
  • Các biến interface là public, static và final theo định nghĩa; chúng ta không được phép thay đổi khả năng hiển thị của chúng.

3. Chúng ta có thể đạt được gì bằng cách sử dụng chúng?

3.1. Chức năng hành vi

Chúng ta sử dụng các interface để thêm chức năng hành vi nhất định có thể được sử dụng bởi các lớp không liên quan. Ví dụ: Có thể Comparable, Comparator, and Cloneable là các Java interface có thể được thực hiện bởi các lớp không liên quan. Dưới đây là một ví dụ về Comparator interface được sử dụng để so sánh hai phiên bản của lớp Employee:

public class Employee {

    private double salary;

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
}

public class EmployeeSalaryComparator implements Comparator<Employee> {

    @Override
    public int compare(Employee employeeA, Employee employeeB) {
        if (employeeA.getSalary() < employeeB.getSalary()) {
            return -1;
        } else if (employeeA.getSalary() > employeeB.getSalary()) { 
            return 1;
        } else {
            return 0;
        }
    }
}

Để biết thêm thông tin, vui lòng truy cập hướng dẫn về Comparator và Comparable trong Java.

3.2. Đa kế thừa

Các lớp Java hỗ trợ đơn kế thừa. Tuy nhiên, bằng cách sử dụng các interface, chúng ta cũng có thể triển khai đa kế thừa.

Ví dụ, chúng ta nhận thấy rằng lớp Car thực hiện các interface Fly và Transform. Bằng cách đó, nó kế thừa các phương thức Fly và Trasform:

public interface Transform {
    void transform();
}

public interface Fly {
    void fly();
}

public class Car implements Fly, Transform {

    @Override
    public void fly() {
        System.out.println("I can Fly!!");
    }

    @Override
    public void transform() {
        System.out.println("I can Transform!!");
    }
}

3.3. Tính đa hình

Hãy bắt đầu với việc đặt câu hỏi: tính đa hình là gì? Đó là khả năng một đối tượng có các dạng khác nhau trong runtime. Cụ thể hơn, đó là việc thực thi phương thức ghi đè có liên quan đến một loại đối tượng cụ thể trong runtime.

Trong Java, chúng ta có thể đạt được tính đa hình bằng cách sử dụng các interface. Ví dụ: Shape interface có thể có các dạng khác nhau - nó có thể là Hình tròn hoặc Hình vuông.

Hãy bắt đầu bằng cách xác định Shape interface:

public interface Shape {
    String name();
}

Bây giờ chúng ta cũng tạo lớp Circle:

public class Circle implements Shape {

    @Override
    public String name() {
        return "Circle";
    }
}

Và cả lớp Square:

public class Square implements Shape {

    @Override
    public String name() {
        return "Square";
    }
}

Cuối cùng, đã đến lúc để xem tính đa hình hoạt động bằng cách sử dụng Shape interface của chúng ta và các triển khai của nó. Hãy khởi tạo một số đối tượng Shape, thêm chúng vào List và cuối cùng, in tên của chúng trong một vòng lặp:

List<Shape> shapes = new ArrayList<>();
Shape circleShape = new Circle();
Shape squareShape = new Square();

shapes.add(circleShape);
shapes.add(squareShape);

for (Shape shape : shapes) {
    System.out.println(shape.name());
}

4. Phương thức mặc định trong interface

Các interface truyền thống trong Java 7 trở xuống không cung cấp khả năng tương thích ngược.

Điều này có nghĩa là nếu bạn có mã kế thừa được viết bằng Java 7 hoặc phiên bản cũ hơn và bạn quyết định thêm một phương thức trừu tượng vào một interface hiện có, thì tất cả các lớp triển khai giao diện đó phải ghi đè phương thức trừu tượng mới. Nếu không, mã sẽ bị hỏng.

Java 8 đã giải quyết vấn đề này bằng cách giới thiệu phương thức mặc định là tùy chọn và có thể được thực hiện ở cấp giao diện.

5. Quy tắc kế thừa interface

Để đạt được đa thừa kế thông qua các giao diện, chúng ta phải nhớ một số quy tắc. Chúng ta hãy xem xét những điều này một cách chi tiết.

5.1. Interface Extending Another Interface

Khi một interface mở rộng một interface khác, nó sẽ kế thừa tất cả các phương thức trừu tượng của interface đó. Hãy bắt đầu bằng cách tạo hai interface, HasColor và Shape:

public interface HasColor {
    String getColor();
}

public interface Box extends HasColor {
    int getHeight()
}

Trong ví dụ trên, Box kế thừa từ HasColor bằng cách sử dụng từ khóa extends. Bằng cách làm như vậy, Box interface kế thừa getColor . Kết quả là Box interface bây giờ có hai phương thức: getColor và getHeight.

5.2. Lớp trừu tượng triển khai một interface

Khi một lớp trừu tượng triển khai một interface, nó sẽ kế thừa tất cả các phương thức trừu tượng và mặc định của nó. Hãy xem xét Transform interface và lớp trừu tượng Vehicle thực hiện nó:

public interface Transform {
    
    void transform();
    default void printSpecs(){
        System.out.println("Transform Specification");
    }
}

public abstract class Vehicle implements Transform {}

Trong ví dụ này, lớp Vehicle kế thừa hai phương thức: phương thức transform trừu tượng và phương thức printSpecs mặc định.

6. Functional Interfaces

Java đã có Functional Interfaces kể từ những ngày đầu tiên của nó, chẳng hạn như có thể so sánh được (kể từ Java 1.2) và Runnable (kể từ Java 1.0).

Java 8 đã giới thiệu các Functional Interfaces mới như Predicate, Consumer và Function. Để tìm hiểu thêm về những điều này, vui lòng truy cập hướng dẫn của chúng tôi về Functional Interfaces trong Java 8.

7. Kết luận

Trong hướng dẫn này, chúng ta đã có cái nhìn tổng quan về các Java Interface và cách sử dụng chúng để đạt được tính đa hình và tính đa kế thừa.

Bình luận

avatar
Bùi Hiên 2022-09-13 04:07:29.929909 +0000 UTC

tuyệt vời =))

Avatar
* Vui lòng trước khi bình luận.
Ảnh đại diện
  0 Thích
0