override và overload trong JAVA

Override và Overload là hai kỹ thuật quan trọng trong Java để thực hiện tính đa hình, một khái niệm quan trọng trong lập trình hướng đối tượng. Do có nhiều sự tương đồng nên khiến các bạn dễ nhầm lẫn. Trong bài viết này, mình sẽ làm rõ điểm khác biệt giữa override và overload giúp các bạn ứng dụng hiệu quả trong lập trình nhé!

Tính đa hình trong Java

Tính đa hình trong Java (polymorphism) là một trong bốn đặc tính cơ bản của lập trình hướng đối tượng (OOP) bên cạnh tính kế thừa (inheritance), tính đóng gói (encapsulation) và tính trừu tượng (abstraction). Tính đa hình cho phép một đối tượng có thể nhận nhiều hình thái khác nhau, giúp tăng tính linh hoạt và tái sử dụng code. Để đạt tính đa hình trong Java, có thể sử dụng 2 phương thức gồm:

  • Overloading (Nạp chồng)
  • Overriding (Ghi đè)

Overload trong Java

Overload (nạp chồng) là việc định nghĩa nhiều phương thức cùng tên trong cùng một lớp nhưng có số lượng hoặc kiểu dữ liệu của tham số khác nhau. Khi gọi một phương thức bị nạp chồng, Java sẽ tự động chọn phương thức phù hợp dựa trên kiểu dữ liệu và số lượng tham số truyền vào.

Quy tắc định nghĩa overload:

  • Các phương thức cùng tên nhưng phải khác tham số (số lượng hoặc kiểu dữ liệu).
  • Phạm vi truy cập (access modifier), kiểu trả về (return type) và ngoại lệ (exceptions) không ảnh hưởng đến quy tắc overload.

Override trong Java

Override (ghi đè) là việc lớp con ghi đè phương thức của lớp cha, thay đổi cách thức thực hiện của phương thức đó. Khi gọi một phương thức đã được ghi đè, phương thức của lớp con sẽ được ưu tiên thực thi thay vì phương thức của lớp cha.

Quy tắc định nghĩa override:

  • Phương thức của lớp con phải cùng tên, cùng tham số và cùng kiểu trả về với phương thức của lớp cha.
  • Phạm vi truy cập (access modifier) của phương thức lớp con phải rộng hơn hoặc bằng phạm vi truy cập của phương thức lớp cha.
  • Nếu phương thức lớp cha ném ra ngoại lệ (throws exception), phương thức lớp con chỉ được phép ném ra các ngoại lệ con của ngoại lệ lớp cha hoặc không ném ra ngoại lệ.

Sự khác biệt giữa Override và Overload

So sánh và giải thích sự khác biệt về cú pháp, tham số và kết quả trả về của Override và Overload

Điểm khác biệtOverrideOverload
Tên phương thứcGiống với phương thức được ghi đèKhác với tên phương thức gốc
Tham sốGiống với phương thức được ghi đèKhác với tham số của phương thức gốc
Kiểu trả vềGiống với phương thức được ghi đèCó thể giống hoặc khác với kiểu trả về của phương thức gốc
ModifierPhải có cùng hoặc phạm vi phương thức trênKhông cần phải có cùng hoặc phạm vi phương thức trên
Thứ tự phương thức được gọiPhương thức được ghi đè được gọiPhương thức tải được gọi dựa trên tham số được truyền vào
Đối tượng được gọiPhương thức trong lớp con được gọiPhương thức được gọi phụ thuộc vào số lượng và kiểu tham số được truyền vào
Kiểu trả vềPhương thức được ghi đè phải có cùng kiểu trả về như phương thức được ghi đèPhương thức được nạp chồng có thể có kiểu trả về khác nhau
Quá trình biên dịchGhi đè được xác định trong quá trình biên dịchNạp chồng được xác định trong quá trình biên dịch và thời gian chạy
Mục đích sử dụngGhi đè thường được sử dụng để triển khai lại phương thức của lớp cha để cung cấp cài đặt tùy chỉnh cho phương thức đóNạp chồng thường được sử dụng để cung cấp nhiều cách để gọi cùng một phương thức với các tham số khác nhau

Ví dụ minh họa

Để hiểu rõ hơn sự khác biệt thực tế giữa overload và override trong Java, chúng ta hãy cùng xem ví dụ sau đây:

public class Shape {
// Tạo lớp Shape với phương thức draw() đơn giản in ra chuỗi “Drawing a shape”.

public void draw() {

System.out.println(“Drawing a shape”);

}

}

public class Circle extends Shape {

// Ghi đè phương thức draw() để in ra chuỗi “Drawing a circle”.

@Override

public void draw() {

System.out.println(“Drawing a circle”);

}

// Nạp chồng phương thức draw() để in ra chuỗi “Drawing a circle with radius X”.

public void draw(int radius) {

System.out.println(“Drawing a circle with radius ” + radius);

}

}

public class Main {

public static void main(String[] args) {

// Tạo đối tượng Shape và Circle.

Shape shape = new Shape();

Circle circle = new Circle();

// Gọi phương thức draw() trên đối tượng Shape.

shape.draw();   // Output: Drawing a shape

// Gọi phương thức draw() trên đối tượng Circle.

circle.draw();  // Output: Drawing a circle

// Gọi phương thức draw() với tham số trên đối tượng Circle.

circle.draw(5); // Output: Drawing a circle with radius 5

}

}

Ta có lớp cha Shape và lớp con Circle. Lớp Shape có một phương thức draw() đơn giản, trong khi lớp Circle có hai phương thức draw(), một phương thức được ghi đè (overriding method) và một phương thức được nạp chồng (overloading method).

  • Override: Phương thức draw() trong lớp Circle được ghi đè lại (override) từ phương thức draw() trong lớp Shape. Khi  phương thức draw() được gọi trên đối tượng Circle, phương thức draw() trong lớp Circle sẽ được gọi thay vì phương thức draw() trong lớp Shape.
  • Overload: Lớp Circle có một phương thức draw() khác với tham số là radius. Khi phương thức draw() được gọi trên đối tượng Circle với tham số là radius, phương thức draw() với tham số radius sẽ được gọi thay vì phương thức draw() được ghi đè từ lớp Shape.

Lợi ích của Override và Overload trong Java

Override và Overload đóng vai trò quan trọng trong việc phát triển tính đa hình:

  • Override giúp thực hiện tính đa hình thông qua việc kế thừa và thay đổi hành vi của phương thức từ lớp cha.
  • Overload giúp thực hiện tính đa hình khi kết hợp với Override, cho phép tạo ra nhiều phương thức với cùng một tên nhưng khác nhau về số lượng hoặc kiểu dữ liệu của tham số.

Sử dụng Override và Overload giúp tăng tính linh hoạt và tái sử dụng code:

  • Tính linh hoạt: Override và Overload giúp dễ dàng điều chỉnh và thay đổi hành vi của phương thức mà không cần thay đổi tên phương thức. Điều này giúp giảm thiểu sự rắc rối trong quá trình lập trình và giúp code dễ đọc hơn.
  • Tái sử dụng code: Override cho phép lớp con kế thừa và thay đổi hành vi của phương thức từ lớp cha, giúp giảm thiểu việc lặp lại code và tận dụng tốt hơn các phương thức đã có sẵn. Overload giúp tạo ra nhiều phương thức với cùng một tên nhưng khác nhau về số lượng hoặc kiểu dữ liệu của tham số, từ đó giúp giảm thiểu việc phải tạo ra nhiều phương thức khác nhau cho cùng một chức năng.

Kết luận

Override và Overload là hai kỹ thuật quan trọng trong Java để thực hiện tính đa hình và tăng tính linh hoạt và tái sử dụng code. Sự khác nhau giữa hai kỹ thuật này cho phép chúng ta áp dụng chúng vào các tình huống khác nhau trong quá trình phát triển phần mềm. Hy vọng bài viết này đã giúp bạn hiểu rõ hơn về Override và Overload trong Java.

Related Posts
Lịch sử ngôn ngữ lập trình Java

Java (phiên âm Tiếng Việt: "Gia-va") là một ngôn ngữ lập trình hướng đối tượng, dựa trên lớp được thiết Read more

Phím tắt trong Eclipse giúp tăng năng suất coding

Các phím tắt sẽ giúp tốc độ coding của bạn nhanh hơn rất nhiều, hơn nữa format code của bạn Read more

Lập trình Hướng đối tượng(OOP)

Lập trình hướng đối tượng (tiếng Anh: Object-oriented programming, viết tắt: OOP) là một mẫu hình lập trình dựa trên Read more

Kiểu dữ liệu Nguyên thủy(Primitive)

1. Tổng quan Trong ngôn ngữ lập trình Java có 2 kiểu dữ liệu chúng ta cần nắm và phân Read more

Hãy bình luận đầu tiên

Để lại một phản hồi