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

Khác biệt giữa Đa hình thời gian biên dịch (Compile-time) và Đa hình thời gian chạy (Runtime) trong Java

Đa hình (Polymorphism) là khả năng thực hiện một hành động theo nhiều cách khác nhau. Java hỗ trợ 2 loại:

1. Compile-time Polymorphism (Static Binding / Early Binding)

  • Còn gọi: Method Overloading (Nạp chồng phương thức).
  • Quyết định phương thức nào được gọi tại thời điểm compile dựa trên signature (tên + tham số).
  • Không liên quan đến inheritance.
  • Static binding – JVM biết chính xác method nào chạy.

2. Runtime Polymorphism (Dynamic Binding / Late Binding)

  • Còn gọi: Method Overriding (Ghi đè phương thức).
  • Quyết định phương thức nào được gọi tại thời điểm chạy dựa trên object thực tế (runtime type).
  • Yêu cầu Inheritance (kế thừa) hoặc Interface implementation.
  • Dynamic binding – JVM tra bảng phương thức ảo (v-table) lúc chạy.

Bảng so sánh

Tiêu chíCompile-time (Overloading)Runtime (Overriding)
Cơ chếStatic bindingDynamic binding
Kế thừaKhông cầnBắt buộc (extends/implements)
SignatureKhác nhau (tham số: số lượng, kiểu, thứ tự)Giống hệt nhau (tên, tham số, return type)
Return typeCó thể khác nhauPhải cùng kiểu hoặc covariant (subtype)
Access modifierTự doKhông hẹp hơn (protected ≥ default ≥ private)
Ví dụ điển hìnhprint(int), print(String), print(Object)Animal.sound() → Dog.sound(), Cat.sound()

Ví dụ Compile-time Polymorphism (Overloading)

public class CompileTimePoly {
    // Overload: khác tham số
    void display() {
        System.out.println("Không tham số");
    }
    void display(String msg) {
        System.out.println("Có tham số: " + msg);
    }
    void display(int a, int b) {
        System.out.println("Hai số: " + a + ", " + b);
    }
    
    public static void main(String[] args) {
        CompileTimePoly obj = new CompileTimePoly();
        obj.display();           // Gọi version 1
        obj.display("Hello");    // Gọi version 2
        obj.display(10, 20);     // Gọi version 3
    }
}

Ví dụ Runtime Polymorphism (Overriding)

class Animal {
    public void sound() {
        System.out.println("Animal makes sound");
    }
}

class Dog extends Animal {
    @Override
    public void sound() {
        System.out.println("Dog barks: Gâu gâu");
    }
}

class Cat extends Animal {
    @Override
    public void sound() {
        System.out.println("Cat meows: Meo meo");
    }
}

public class RuntimePoly {
    public static void main(String[] args) {
        Animal a1 = new Dog();   // Reference Animal, Object Dog
        Animal a2 = new Cat();   // Reference Animal, Object Cat
        
        a1.sound(); // Runtime: gọi Dog.sound() → "Dog barks"
        a2.sound(); // Runtime: gọi Cat.sound() → "Cat meows"
        
        // Có thể dùng mảng/collection Animal chứa nhiều subclass
        Animal[] animals = {new Dog(), new Cat(), new Animal()};
        for (Animal a : animals) a.sound();
    }
}

Tóm tắt

  • Overloading = cùng class, khác signature → compile-time.
  • Overriding = parent-child, cùng signature → runtime.
  • Java dùng dynamic method dispatch cho overriding – nền tảng của OOP linh hoạt.
  • @Override annotation giúp compile-time check lỗi overriding (sai signature, final method...).