STDIO
Tìm kiếm gần đây
    • 0

    Overloading Method - Nạp Chồng Hàm Trong Java

    Cơ chế hoạt động nạp chồng phương thức - method overloading trong Java.
    17/08/2015
    04/08/2020
    5 phút đọc
    Overloading Method - Nạp Chồng Hàm Trong Java

    Nạp chồng phương thức - Method Overloading 

    Khái niệm

    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 overload

    Sử 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ố.

    • Giả sử không có overload, định nghĩa các hàm tính tổng 2, 3, 4 tham số:
      • Phương thức cộng 2 số: int sum2(int a, int b)
      • Phương thức cộng 3 số: int sum3(int a, int b, int c)
      • Phương thức cộng 4 số: int sum4(int a, int b, int c, int d)
    • Áp dụng overload:
      • Phương thức cộng 2 số: int sum(int a, int b)
      • Phương thức cộng 3 số: int sum(int a, int b, int c)
      • Phương thức cộng 4 số: int sum(int a, int b, int c, int d)

    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ản

    Có 2 cách để tạo ra hiện tượng overload:

    • Thay đổi số lượng tham số.
    • Thay đổi kiểu dữ liệu của tham số.

    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);
    }
    • obj.add(10, 10) gọi phương thức void add(int param1, int param2) do cả 2 tham số truyền vào đều là kiểu int.
    • obj.add(10.5f, 10.24f) gọi phương thức void add(float param1, float param2) do cả 2 tham số truyền vào đều là kiểu float.

    Ở 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 intIntegervoid method(Integer param) và một kiểu rộng hơn kiểu intlongvoid 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ừa

    Quan 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ả:

    • Animal eats everything
    • Dogs eat meat
    • Animal eats everything

    Kết quả của dòng thứ 3 có thể gây bối rối:

    • Animal animal_obj = new Dog() khởi tạo một đối tượng Dog và gán cho một tham chiếu kiểu Animal.
    • Như vậy obj.eat(animal_obj) - phương thức eat có tham số kiểu Dog sẽ được gọi, nhưng ở đây, trình biên dịch lại gọi phương thức eat có tham số kiểu Animal.
      • Vì tham chiếu animal_obj chỉ xác định được đối tượng nó tham chiếu thực sự tới là đối tượng nào tại quá trình runtime, điều đó đồng nghĩa với, trong khi biên dịch (compile) animal_obj chưa hề biết đối tượng nó thực sự tham chiếu tới trên heap và trình biên dịch chỉ biết về animal_obj có kiểu dữ liệu là Animal.
      • Trong khi đó, việc quyết định chọn phương thức trong danh sách phương thức overload lại được trình biên dịch quyết định trong quá trình compile, nên trình biên dịch sẽ quyết định phương thức overload được gọi dựa vào kiểu dữ liệu của tham chiếu (Animal), không phải dựa vào kiểu dữ liệu của đối tượng được tham chiếu tới (Dog).
    Java

    Java

    Tổng hợp các bài viết Java hữu ích

    Sản phẩm

    Đề xuất

    Nạp Chồng Hàm (Function Overloading)

    Nạp Chồng Hàm (Function Overloading)

    Hướng dẫn nạp chồng hàm - function overloading trong C++.

    Modern C++C++0x

    04/02/2015

    Ghi Đè Phương Thức - Overriding Method trong Java

    Ghi Đè Phương Thức - Overriding Method trong Java

    Trong Java, ghi đè phương thức - overriding method là phương pháp "viết ...

    JavaCơ Bản

    27/05/2015

    Khám phá thêm

    template Trong C++

    template Trong C++

    Tìm hiểu về từ khoá template trong C++.

    Modern C++C++98

    21/09/2014

    String Trong Java

    String Trong Java

    Giới thiệu về kiểu chuỗi và kỹ thuật thao tác với chuỗi trong ngôn ngữ ...

    JavaCơ Bản

    06/05/2015

    Tổng Quan về Ngôn Ngữ Lập Trình Java

    Tổng Quan về Ngôn Ngữ Lập Trình Java

    Java là 1 trong những ngôn ngữ lập trình mạnh mẽ, được sử dụng rộng rãi ...

    JavaKiến Thức

    20/05/2015

    Lập Trình Multithreading trong Ngôn Ngữ Lập Trình Java

    Lập Trình Multithreading trong Ngôn Ngữ Lập Trình Java

    Trong chương trình của chúng ta đôi khi ta cần thực thi nhiều tác vụ ...

    JavaNâng Cao

    19/11/2015

    Custom Event trong Java

    Custom Event trong Java

    Khái niệm event rất quen thuộc với lập trình giao diện, sự kiện khi nhấn ...

    JavaCơ Bản

    19/11/2015

    Hàm Tạo Mặc Định trong Lập Trình Hướng Đối Tượng

    Hàm Tạo Mặc Định trong Lập Trình Hướng Đối Tượng

    Phân tích sự khác biệt giữa hàm tạo mặc định và hàm tạo không đối số ...

    Modern C++Nâng cao

    19/08/2015

    Ngôn Ngữ C++ - Lịch Sử Hình Thành và Phát Triển

    Ngôn Ngữ C++ - Lịch Sử Hình Thành và Phát Triển

    Lịch sử phát triển và lý do tại sao C++ lại là nền tảng cho tất cả lập ...

    Modern C++Nâng cao

    27/09/2014

    Hiện Thực Và Sử Dụng Hàm strcmp - strcpy - strlen Trong C/C++

    Hiện Thực Và Sử Dụng Hàm strcmp - strcpy - strlen Trong C/C++

    Hướng dẫn sử dụng hàm strlen để lấy độ dài chuỗi, hàm strcmp để so sánh ...

    Modern C++C++98

    21/08/2015

    STDIO
    Trang chính
    Công ty TNHH STDIO

    30, Trịnh Đình Thảo, Hòa Thạnh, Tân Phú, Hồ Chí Minh
    +84 28.36205514 - +84 942.111912
    developer@stdio.vn

    383/1 Quang Trung, Phường 10, Quận Gò Vấp, Hồ Chí Minh
    Số giấy phép ĐKKD: 0311563559 do sở Kế hoạch và Đầu Tư TPHCM cấp ngày 23/02/2012

    ©STDIO, 2013 - 2020