Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Java

Khác biệt giữa Default Method và Static Method trong Interface Java 8

Java 8 cho phép định nghĩa method có implementation trong interface thông qua default method và static method. Đây là bước tiến lớn cho backward compatibility và thiết kế API.

Bảng so sánh

Tiêu chíDefault MethodStatic Method
Từ khóadefaultstatic
Đối tượng gọiInstance của class implements interfaceInterface tên (InterfaceName.method())
OverrideCó thể override trong implementing classKhông thể override (chỉ hide – method hiding)
Truy cập thisCó (gọi instance method khác)Không (không có instance context)
Kế thừaKế thừa cho sub-interface & implementing classKhông kế thừa (chỉ truy cập qua InterfaceName)
Mục đích chínhMở rộng interface mà không break implementing classes. Cung cấp implementation chung.Utility/helper methods gắn liền với interface (factory, helper).
Multiple inheritance conflictPhải override nếu 2 interface có default method trùng signatureKhông conflict (gọi qua InterfaceName rõ ràng)

Ví dụ minh họa

interface Vehicle {
    // Default method: có implementation, có thể override
    default void start() {
        System.out.println("Vehicle starting... (default)");
        checkEngine(); // Gọi private method
    }
    
    // Static method: utility, gọi qua Vehicle.checkEngine()
    static void checkEngine() {
        System.out.println("Engine check: OK");
    }
    
    // Private method (Java 9+) – helper cho default/static trong interface
    private void log(String msg) {
        System.out.println("[LOG] " + msg);
    }
    
    // Abstract method – bắt buộc implement
    void move();
}

class Car implements Vehicle {
    @Override
    public void move() {
        System.out.println("Car moving on 4 wheels");
    }
    
    // Override default method
    @Override
    public void start() {
        Vehicle.checkEngine(); // Gọi static method của interface
        System.out.println("Car engine started!");
    }
}

class Bike implements Vehicle {
    @Override
    public void move() {
        System.out.println("Bike moving on 2 wheels");
    }
    // Không override start() → dùng default của Vehicle
}

public class InterfaceMethodsDemo {
    public static void main(String[] args) {
        Vehicle car = new Car();
        Vehicle bike = new Bike();
        
        car.start();  // Car engine started! (overridden)
        bike.start(); // Vehicle starting... (default)
        
        // Static method gọi qua Interface
        Vehicle.checkEngine(); // Engine check: OK
        
        // Polymorphism
        Vehicle[] vehicles = {car, bike};
        for (Vehicle v : vehicles) v.move();
    }
}

Quy tắc Diamond Problem (Multiple Default Methods)

interface A { default void foo() { System.out.println("A"); } }
interface B { default void foo() { System.out.println("B"); } }

// Class implements cả 2 → BẮT BUỘC override foo()
class C implements A, B {
    @Override
    public void foo() {
        A.super.foo(); // Gọi explicit default của A
        // hoặc B.super.foo();
    }
}

Best Practices

  • Dùng default method để evolve API (thêm method mới vào interface cũ) mà không ép tất cả implementer phải sửa code.
  • Dùng static method cho utility methods (factory, validation, helper) liên quan chặt chẽ đến interface.
  • Java 9+: Dùng private method trong interface để chia sẻ code giữa default/static methods.
  • Tránh lạm dụng default method – interface nên tập trung vào contract (what), không phải implementation (how).