Overloading là gì
Show Overloading (Nạp chồng phương thức) và Overriding (ghi đè phương thức) là hai khái niệm cơ bản trong lập trình mà bất kì newbie nào cũng cần phân biệt. Vậy chúng là gì? Khác nhau thế nào? Hãy cùng Hybrid Technologies phân tích và tìm hiểu trong bài viết này nhé! Overloading (Nạp chồng phương thức) là gì?Overloading là một kĩ thuật cho phép trong cùng một class có thể có nhiều phương thức cùng tên nhưng khác nhau về số lượng tham số hoặc kiểu dữ liệu tham số. Ví dụ chúng ta có hàm tinhTong dùng để cộng hai số nguyên. Khi muốn cộng ba số nguyên, bạn phải viết một hàm với tên khác (chẳng hạn tinhTong1) và truyền vào 3 số nguyên? Như vậy, code sẽ trở nên phức tạp hơn trong khi hai hàm có cùng một mục đích là cộng các số nguyên lại với nhau. Như vậy chúng ta sẽ overload hàm tinhTong như sau: Khi gọi hàm tinhTong và truyền vào số lượng tham số khác nhau thì sẽ gọi tới hàm có số lượng tham số tương ứng Chú ý vào cửa sổ “Watch 1” ta thấy giá trị của hai biến a và b lần lượt là giá trị trả về của hai hàm tinhTong(int a, int b) và hàm tinhTong(int a, int b, int c) Tương tự ta có thể overload kiểu dữ liệu của tham số. Thay vì hàm tinhTong cộng hai số nguyên thì cũng có thể cộng hai số thực, chỉ cần truyền vào 2 tham số kiểu double. Bạn đang xem: Overload là gì Tương tự giá trị biến c là giá trị trả về của hàm tinhTong(double a, double b) sau khi truyền vào hai tham số kiểu double. Tạo constructor với số lượng tham số khác nhau cũng là một dạng của oveloading. Xem thêm: Hướng Dẫn Chơi Coin Master Cho Người Mới Bắt Đầu, Hướng Dẫn Chơi Game Coin Master Cho Người Mới Overriding (Ghi đè phương thức) là gì?Overrding (tên đầy đủ là Method Overriding), được sử dụng trong trường hợp lớp con kế thừa từ lớp cha và muốn định nghĩa lại một phương thức đã có mặt ở lớp cha. Một lớp cha thông thường có thể có nhiều lớp con kế thừa, tuy nhiên phương thức ở lớp cha có thể phù hợp với lớp con này nhưng không phù hợp với lớp con khác, do đó lớp con cần ghi đè lại phương thức đó cho phù hợp. Ví dụ class Animal có phương thức animalSound đại diện cho tiếng kêu của động vật. Class Dog và Cat kế thừa từ class Animal, nhưng chó và mèo có tiếng kêu khác nhau nên phải implement phương thức animalSound cho mỗi lớp khác nhau. Vì vậy cần phải ghi đè lại phương thức animalSound ở hai lớp Dog và Cat bằng cách sử dụng từ khóa override như sau(lưu ý ví dụ minh họa sử dụng code C#, những ngôn ngữ khác nhau sẽ overriding theo cú pháp khác nhau nhưng về bản chất là như nhau). Ở hàm main tạo instance của class Animal, Dog và Cat sẽ cho kết quả như sau. => Kết quả So sánh
Hy vọng qua bài viết này, các bạn sẽ hiểu rõ hơn và không còn nhầm lẫn giữa hai khái niệm trên. Chúc các bạn luôn thành công! Tương tự như khái niệm nạp chồng hàm trong C++, nạp chồng phương thức (method overloading) trong Java là hiện tượng nhiều phương thức có cùng tên, tuy nhiên số lượng tham số hoặc kiểu của tham số trong các phương thức này là khác nhau trong cùng 1 class hoặc trong xuyên suốt các class có quan hệ kế thừa. Chú ý: Các phương thức có cùng tên, cùng danh sách tham số, tuy nhiên, kiểu trả về khác nhau không được xem là overload. Tác dụng và cơ chế của overloadSử dụng overload trong một chương trình nhằm tăng khả năng tổ chức cho chương trình khi các hàm có gần ý nghĩa, mục đích chỉ khác về tham số.
Trình biên dịch sẽ dựa vào tham số được truyền vào phương thức mà quyết định xem sẽ gọi phương thức nào trong danh sách phương thức overload. Overload với tham số kiểu cơ bảnCó 2 cách để tạo ra hiện tượng overload:
Thay đổi số lượng tham sốĐây là trường hợp dễ nhận biết nhất của overload: public class Stdio { private static final String address = "stdio.vn"; private String author; Stdio() { writer = ""; } Stdio(String writer) { this.writer = writer; } public static void main(String[] args) { // Call no arguments constructor Stdio obj = new Stdio(); System.out.println(obj.writer); // Call constructor has a argument Stdio obj1 = new Stdio("Alice"); System.out.println(obj1.writer); } }Đoạn code trên thực hiện overload constructor của lớp Stdio với 1 constructor không có tham số và 1 constructor có chứa 1 tham số. Thay đổi kiểu dữ liệu của tham sốKhi có cùng số lượng tham số, trình biên dịch sẽ dựa vào kiểu của đối số được truyền vào phương thức, sau đó đối chiếu với kiểu dữ liệu của tham số của phương thức để chọn ra phương thức thích hợp nhất. void add(int param1, int param2) { System.out.println(param1 + param2); } void add(float param1, float param2) { System.out.println(param1 + param2); } public static void main(String[] args) { Calculation obj = new Calculation(); obj.add(10, 10); obj.add(10.5f, 10.24f); }
Ở một khía cạnh khác, hiện tượng ép kiểu và lớp bao trong Java được sử dụng như thế nào trong nạp chồng phương thức. Quan sát ví dụ dưới đây: public class TestOverload { void method(Integer param) { System.out.println("_Integer invoked"); } void method(long param) { System.out.println("_long invoked"); } public static void main(String[] args) { Calculation obj = new Calculation(); obj.method(10); } }Kết quả là: _long invoked obj.method(10) khi truyền 10 là một đối số kiểu int, trình biên dịch kiểm tra xem có phương thức nào có tham số là kiểu int hay không nhưng không tìm thấy. Thay vào đó, nó tìm thấy 2 phương thức có tham số là lớp bao của kiểu int là Integer - void method(Integer param) và một kiểu rộng hơn kiểu int là long - void method(long param), trình biên dịch sẽ ưu tiên gọi phương thức có tham số có kiểu rộng hơn đối số truyền vào thay vì phương thức có tham số là lớp bao của đối số truyền vào. Overload và quan hệ kế thừaQuan hệ kế thừa thường đề cập tới mối quan hệ IS-A. Nói cách khác, một đối tượng thuộc lớp con cũng là một đối tượng thuộc lớp cha. Vì thế, khi thực hiện overload phương thức hoàn toàn có thể truyền một đối tượng thuộc lớp con vào một phương thức trong danh sách phương thức overload có tham số mang kiểu dữ liệu của lớp cha. class Animal {} class Dog extends Animal {} public class Test_Animal { void eat(Animal animal) { System.out.println("Animal eats everything"); } void eat(Dog dog) { System.out.println("Dogs eat meat"); } public static void main(String[] args) { Test_Animal obj = new Test_Animal(); Animal animal = new Animal(); Dog dog = new Dog(); Animal animal_obj = new Dog(); obj.eat(animal); obj.eat(dog); obj.eat(animal_obj); } }Kết quả:
Kết quả của dòng thứ 3 có thể gây bối rối:
|